Skip to content

Commit 75635b0

Browse files
committed
add benchmark
Signed-off-by: yeya24 <[email protected]>
1 parent e2dd641 commit 75635b0

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

pkg/ingester/ingester_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"github.com/thanos-io/thanos/pkg/runutil"
4343
"github.com/thanos-io/thanos/pkg/shipper"
4444
storecache "github.com/thanos-io/thanos/pkg/store/cache"
45+
"github.com/thanos-io/thanos/pkg/store/storepb"
4546
"github.com/weaveworks/common/httpgrpc"
4647
"github.com/weaveworks/common/middleware"
4748
"github.com/weaveworks/common/user"
@@ -3941,6 +3942,119 @@ func BenchmarkIngester_QueryStream_Chunks(b *testing.B) {
39413942
}
39423943
}
39433944

3945+
func BenchmarkIngester_QueryStreamChunks_MatcherOptimization(b *testing.B) {
3946+
tests := map[string]struct {
3947+
matchers []*labels.Matcher
3948+
description string
3949+
}{
3950+
"metric name with regex matchers": {
3951+
matchers: []*labels.Matcher{
3952+
labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, "test_metric"),
3953+
labels.MustNewMatcher(labels.MatchRegexp, "region", ".+"),
3954+
labels.MustNewMatcher(labels.MatchRegexp, "job", ".+"),
3955+
},
3956+
description: "Metric name with .+ regex matchers",
3957+
},
3958+
"metric name with not equal empty": {
3959+
matchers: []*labels.Matcher{
3960+
labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, "test_metric"),
3961+
labels.MustNewMatcher(labels.MatchNotEqual, "env", ""),
3962+
labels.MustNewMatcher(labels.MatchNotEqual, "pod", ""),
3963+
},
3964+
description: "Metric name with != \"\" matchers",
3965+
},
3966+
"complex matchers": {
3967+
matchers: []*labels.Matcher{
3968+
labels.MustNewMatcher(labels.MatchEqual, model.MetricNameLabel, "test_metric"),
3969+
labels.MustNewMatcher(labels.MatchRegexp, "region", ".+"),
3970+
labels.MustNewMatcher(labels.MatchRegexp, "job", ".+"),
3971+
labels.MustNewMatcher(labels.MatchRegexp, "env", ".+"),
3972+
labels.MustNewMatcher(labels.MatchRegexp, "pod", ".+"),
3973+
},
3974+
description: "Complex matchers with .+ regex",
3975+
},
3976+
}
3977+
3978+
for testName, testData := range tests {
3979+
b.Run(testName+"_optimization_disabled", func(b *testing.B) {
3980+
benchmarkQueryStreamChunksWithMatcherOptimization(b, false, testData.matchers, testData.description+" without optimization")
3981+
})
3982+
b.Run(testName+"_optimization_enabled", func(b *testing.B) {
3983+
benchmarkQueryStreamChunksWithMatcherOptimization(b, true, testData.matchers, testData.description+" with optimization")
3984+
})
3985+
}
3986+
}
3987+
3988+
func benchmarkQueryStreamChunksWithMatcherOptimization(b *testing.B, enableMatcherOptimization bool, matchers []*labels.Matcher, description string) {
3989+
cfg := defaultIngesterTestConfig(b)
3990+
cfg.EnableMatcherOptimization = enableMatcherOptimization
3991+
3992+
i, err := prepareIngesterWithBlocksStorage(b, cfg, prometheus.NewRegistry())
3993+
require.NoError(b, err)
3994+
require.NoError(b, services.StartAndAwaitRunning(context.Background(), i))
3995+
defer services.StopAndAwaitTerminated(context.Background(), i) //nolint:errcheck
3996+
3997+
// Wait until it's ACTIVE
3998+
test.Poll(b, 1*time.Second, ring.ACTIVE, func() any {
3999+
return i.lifecycler.GetState()
4000+
})
4001+
4002+
ctx := user.InjectOrgID(context.Background(), userID)
4003+
4004+
for s := 0; s < 1000; s++ {
4005+
lbls := labels.FromStrings(
4006+
labels.MetricName, "test_metric",
4007+
"region", fmt.Sprintf("region-%d", s%10),
4008+
"job", fmt.Sprintf("job-%d", s%20),
4009+
"env", fmt.Sprintf("env-%d", s%5),
4010+
"pod", fmt.Sprintf("pod-%d", s%1000),
4011+
)
4012+
4013+
samples := make([]cortexpb.Sample, 0, 5)
4014+
for t := 0; t < 5; t++ {
4015+
samples = append(samples, cortexpb.Sample{
4016+
Value: float64(s + t),
4017+
TimestampMs: int64(s*5 + t),
4018+
})
4019+
}
4020+
4021+
// Create labels slice with same length as samples
4022+
labelsSlice := make([]labels.Labels, len(samples))
4023+
for j := range labelsSlice {
4024+
labelsSlice[j] = lbls
4025+
}
4026+
4027+
req := cortexpb.ToWriteRequest(labelsSlice, samples, nil, nil, cortexpb.API)
4028+
_, err = i.Push(ctx, req)
4029+
require.NoError(b, err)
4030+
}
4031+
4032+
db, err := i.getTSDB(userID)
4033+
require.NoError(b, err)
4034+
require.NotNil(b, db)
4035+
4036+
mockStream := &mockQueryStreamServer{ctx: ctx}
4037+
sm := (&storepb.ShardInfo{
4038+
TotalShards: 0,
4039+
}).Matcher(nil)
4040+
4041+
b.ReportAllocs()
4042+
b.ResetTimer()
4043+
4044+
for b.Loop() {
4045+
numSeries, numSamples, _, numChunks, err := i.queryStreamChunks(
4046+
ctx, db, 0, 5000, matchers, sm, mockStream)
4047+
4048+
require.NoError(b, err)
4049+
require.Greater(b, numSeries, 0)
4050+
require.Greater(b, numSamples, 0)
4051+
require.Greater(b, numChunks, 0)
4052+
4053+
// Reset the mock stream for next iteration
4054+
mockStream.series = mockStream.series[:0]
4055+
}
4056+
}
4057+
39444058
func benchmarkQueryStream(b *testing.B, samplesCount, seriesCount int) {
39454059
cfg := defaultIngesterTestConfig(b)
39464060

0 commit comments

Comments
 (0)