Skip to content

Commit

Permalink
store: label_values: fetch less postings (#7814)
Browse files Browse the repository at this point in the history
* label_values: fetch less postings

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

* CHANGELOG.md

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

* added acceptance test

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

* removed redundant comment

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

* check if matcher is EQ matcher

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

* Update CHANGELOG.md

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>

---------

Signed-off-by: Vasiliy Rumyantsev <4119114+xBazilio@users.noreply.github.com>
  • Loading branch information
xBazilio authored Oct 17, 2024
1 parent fe51bd6 commit 274f95e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re
- [#7658](https://github.com/thanos-io/thanos/pull/7658) Store: Fix panic because too small buffer in pool.
- [#7643](https://github.com/thanos-io/thanos/pull/7643) Receive: fix thanos_receive_write_{timeseries,samples} stats
- [#7644](https://github.com/thanos-io/thanos/pull/7644) fix(ui): add null check to find overlapping blocks logic
- [#7814](https://github.com/thanos-io/thanos/pull/7814) Store: label_values: if matchers contain __name__=="something", do not add <labelName> != "" to fetch less postings.
- [#7679](https://github.com/thanos-io/thanos/pull/7679) Query: respect store.limit.* flags when evaluating queries
- [#7821](https://github.com/thanos-io/thanos/pull/7679) Query/Receive: Fix coroutine leak introduced in https://github.com/thanos-io/thanos/pull/7796.

Expand Down
40 changes: 40 additions & 0 deletions pkg/store/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,46 @@ func testStoreAPIsAcceptance(t *testing.T, startStore startStoreFn) {
},
},
},
{
desc: "label_values(kube_pod_info{}, pod) don't fetch postings for pod!=''",
appendFn: func(app storage.Appender) {
_, err := app.Append(0, labels.FromStrings("__name__", "up", "pod", "pod-1"), timestamp.FromTime(now), 1)
testutil.Ok(t, err)
_, err = app.Append(0, labels.FromStrings("__name__", "up", "pod", "pod-2"), timestamp.FromTime(now), 1)
testutil.Ok(t, err)
_, err = app.Append(0, labels.FromStrings("__name__", "kube_pod_info", "pod", "pod-1"), timestamp.FromTime(now), 1)
testutil.Ok(t, err)
testutil.Ok(t, app.Commit())
},
labelNameCalls: []labelNameCallCase{
{
start: timestamp.FromTime(minTime),
end: timestamp.FromTime(maxTime),
expectedNames: []string{"__name__", "pod", "region"},
matchers: []storepb.LabelMatcher{{Type: storepb.LabelMatcher_EQ, Name: "__name__", Value: "kube_pod_info"}},
},
{
start: timestamp.FromTime(minTime),
end: timestamp.FromTime(maxTime),
expectedNames: []string{"__name__", "pod", "region"},
},
},
labelValuesCalls: []labelValuesCallCase{
{
start: timestamp.FromTime(minTime),
end: timestamp.FromTime(maxTime),
label: "pod",
expectedValues: []string{"pod-1"},
matchers: []storepb.LabelMatcher{{Type: storepb.LabelMatcher_EQ, Name: "__name__", Value: "kube_pod_info"}},
},
{
start: timestamp.FromTime(minTime),
end: timestamp.FromTime(maxTime),
label: "pod",
expectedValues: []string{"pod-1", "pod-2"},
},
},
},
} {
t.Run(tc.desc, func(t *testing.T) {
appendFn := tc.appendFn
Expand Down
30 changes: 27 additions & 3 deletions pkg/store/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,14 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR

resHints := &hintspb.LabelValuesResponseHints{}

var hasMetricNameEqMatcher = false
for _, m := range reqSeriesMatchers {
if m.Name == labels.MetricName && m.Type == labels.MatchEqual {
hasMetricNameEqMatcher = true
break
}
}

g, gctx := errgroup.WithContext(ctx)

var reqBlockMatchers []*labels.Matcher
Expand All @@ -2013,6 +2021,7 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
var seriesLimiter = s.seriesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("series", tenant))
var bytesLimiter = s.bytesLimiterFactory(s.metrics.queriesDropped.WithLabelValues("bytes", tenant))
var logger = s.requestLoggerFunc(ctx, s.logger)
var stats = &queryStats{}

for _, b := range s.blocks {
b := b
Expand All @@ -2031,7 +2040,8 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR

// If we have series matchers and the Label is not an external one, add <labelName> != "" matcher
// to only select series that have given label name.
if len(reqSeriesMatchersNoExtLabels) > 0 && !b.extLset.Has(req.Label) {
// We don't need such matcher if matchers already contain __name__=="something" matcher.
if !hasMetricNameEqMatcher && len(reqSeriesMatchersNoExtLabels) > 0 && !b.extLset.Has(req.Label) {
m, err := labels.NewMatcher(labels.MatchNotEqual, req.Label, "")
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
Expand Down Expand Up @@ -2099,7 +2109,12 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
s.metrics.lazyExpandedPostingSeriesOverfetchedSizeBytes,
tenant,
)
defer blockClient.Close()
defer func() {
mtx.Lock()
stats = blockClient.MergeStats(stats)
mtx.Unlock()
blockClient.Close()
}()

if err := blockClient.ExpandPostings(
sortedReqSeriesMatchersNoExtLabels,
Expand Down Expand Up @@ -2128,7 +2143,7 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR
}

val := labelpb.ZLabelsToPromLabels(ls.GetSeries().Labels).Get(req.Label)
if val != "" { // Should never be empty since we added labelName!="" matcher to the list of matchers.
if val != "" {
values[val] = struct{}{}
}
}
Expand All @@ -2152,6 +2167,15 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR

s.mtx.RUnlock()

defer func() {
if s.debugLogging {
level.Debug(logger).Log("msg", "stats query processed",
"request", req,
"tenant", tenant,
"stats", fmt.Sprintf("%+v", stats), "err", err)
}
}()

if err := g.Wait(); err != nil {
code := codes.Internal
if s, ok := status.FromError(errors.Cause(err)); ok {
Expand Down

0 comments on commit 274f95e

Please sign in to comment.