-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Cache labels and series results #3315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,11 +29,16 @@ func newThanosCacheKeyGenerator(interval time.Duration) thanosCacheKeyGenerator | |
| // GenerateCacheKey generates a cache key based on the Request and interval. | ||
| func (t thanosCacheKeyGenerator) GenerateCacheKey(_ string, r queryrange.Request) string { | ||
| currentInterval := r.GetStart() / t.interval.Milliseconds() | ||
| if tr, ok := r.(*ThanosQueryRangeRequest); ok { | ||
| switch tr := r.(type) { | ||
| case *ThanosQueryRangeRequest: | ||
| i := 0 | ||
| for ; i < len(t.resolutions) && t.resolutions[i] > tr.MaxSourceResolution; i++ { | ||
| } | ||
| return fmt.Sprintf("%s:%d:%d:%d", tr.Query, tr.Step, currentInterval, i) | ||
| case *ThanosLabelsRequest: | ||
| return fmt.Sprintf("%s:%d", tr.Label, currentInterval) | ||
| case *ThanosSeriesRequest: | ||
| return fmt.Sprintf("%s:%d", tr.Matchers, currentInterval) | ||
| } | ||
| return fmt.Sprintf("%s:%d:%d", r.GetQuery(), r.GetStep(), currentInterval) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we error here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure but this shouldn't happen. It would error out in the first place when decoding the HTTP request if the request is not valid. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,8 +114,9 @@ func (r *ThanosLabelsRequest) GetStart() int64 { return r.Start } | |
| // GetEnd returns the end timestamp of the request in milliseconds. | ||
| func (r *ThanosLabelsRequest) GetEnd() int64 { return r.End } | ||
|
|
||
| // GetStep returns the step of the request in milliseconds. | ||
| func (r *ThanosLabelsRequest) GetStep() int64 { return 0 } | ||
| // GetStep returns the step of the request in milliseconds. Returns 1 is a trick to avoid panic in | ||
| // https://github.com/cortexproject/cortex/blob/master/pkg/querier/queryrange/results_cache.go#L447. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (: Yea it's getting very tricky without Cortex actually support our case, and it would be nice to help them as well 🤔
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I will take a look later. Would be good to have these query APIs natively supported on Cortex then we can re-use. |
||
| func (r *ThanosLabelsRequest) GetStep() int64 { return 1 } | ||
|
|
||
| // GetQuery returns the query of the request. | ||
| func (r *ThanosLabelsRequest) GetQuery() string { return "" } | ||
|
|
@@ -183,8 +184,9 @@ func (r *ThanosSeriesRequest) GetStart() int64 { return r.Start } | |
| // GetEnd returns the end timestamp of the request in milliseconds. | ||
| func (r *ThanosSeriesRequest) GetEnd() int64 { return r.End } | ||
|
|
||
| // GetStep returns the step of the request in milliseconds. | ||
| func (r *ThanosSeriesRequest) GetStep() int64 { return 0 } | ||
| // GetStep returns the step of the request in milliseconds. Returns 1 is a trick to avoid panic in | ||
| // https://github.com/cortexproject/cortex/blob/master/pkg/querier/queryrange/results_cache.go#L447. | ||
| func (r *ThanosSeriesRequest) GetStep() int64 { return 1 } | ||
|
|
||
| // GetQuery returns the query of the request. | ||
| func (r *ThanosSeriesRequest) GetQuery() string { return "" } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright (c) The Thanos Authors. | ||
| // Licensed under the Apache License 2.0. | ||
|
|
||
| package queryfrontend | ||
|
|
||
| import ( | ||
| "unsafe" | ||
|
|
||
| "github.com/cortexproject/cortex/pkg/querier/queryrange" | ||
| ) | ||
|
|
||
| // ThanosResponseExtractor helps extracting specific info from Query Response. | ||
| type ThanosResponseExtractor struct{} | ||
|
|
||
| // Extract extracts response for specific a range from a response. | ||
| // This interface is not used for labels and series responses. | ||
| func (ThanosResponseExtractor) Extract(_, _ int64, resp queryrange.Response) queryrange.Response { | ||
| return resp | ||
| } | ||
|
|
||
| // ResponseWithoutHeaders returns the response without HTTP headers. | ||
| func (ThanosResponseExtractor) ResponseWithoutHeaders(resp queryrange.Response) queryrange.Response { | ||
| switch tr := resp.(type) { | ||
| case *ThanosLabelsResponse: | ||
| return &ThanosLabelsResponse{Status: queryrange.StatusSuccess, Data: tr.Data} | ||
| case *ThanosSeriesResponse: | ||
| return &ThanosSeriesResponse{Status: queryrange.StatusSuccess, Data: tr.Data} | ||
| } | ||
| return resp | ||
| } | ||
|
|
||
| // headersToQueryRangeHeaders convert slice of ResponseHeader to Cortex queryrange.PrometheusResponseHeader in an | ||
| // unsafe manner. It reuses the same memory. | ||
| func headersToQueryRangeHeaders(headers []*ResponseHeader) []*queryrange.PrometheusResponseHeader { | ||
| return *(*[]*queryrange.PrometheusResponseHeader)(unsafe.Pointer(&headers)) | ||
| } | ||
|
|
||
| // GetHeaders returns the HTTP headers in the response. | ||
| func (m *ThanosLabelsResponse) GetHeaders() []*queryrange.PrometheusResponseHeader { | ||
| return headersToQueryRangeHeaders(m.Headers) | ||
| } | ||
|
|
||
| // GetHeaders returns the HTTP headers in the response. | ||
| func (m *ThanosSeriesResponse) GetHeaders() []*queryrange.PrometheusResponseHeader { | ||
| return headersToQueryRangeHeaders(m.Headers) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about label names?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ThanosLabelsRequestalready covers bothlabel_valuesquery andlabel_namesquery. If it is alabel_namesquery, thentr.Labelis just an empty string. Forlabel_valuesquery, that's the queried label name.I am using the same struct for them since their query response is the same []string