From 67a2e881af707f71ba75763552a12977c5efe12f Mon Sep 17 00:00:00 2001 From: Pedro Tanaka Date: Thu, 5 Dec 2024 11:23:53 +0100 Subject: [PATCH] improve metrics Signed-off-by: Pedro Tanaka --- pkg/store/storepb/matcher_cache.go | 19 ++++++++++++++-- pkg/store/storepb/matcher_cache_test.go | 29 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/pkg/store/storepb/matcher_cache.go b/pkg/store/storepb/matcher_cache.go index c1a77ba061..5d77d73711 100644 --- a/pkg/store/storepb/matcher_cache.go +++ b/pkg/store/storepb/matcher_cache.go @@ -17,7 +17,7 @@ type NewItemFunc func(matcher LabelMatcher) (*labels.Matcher, error) type MatchersCache struct { reg prometheus.Registerer - cache *lru.TwoQueueCache[LabelMatcher, *labels.Matcher] + cache *lru.Cache[LabelMatcher, *labels.Matcher] metrics *matcherCacheMetrics size int sf singleflight.Group @@ -48,7 +48,7 @@ func NewMatchersCache(opts ...MatcherCacheOption) (*MatchersCache, error) { } cache.metrics = newMatcherCacheMetrics(cache.reg) - lruCache, err := lru.New2Q[LabelMatcher, *labels.Matcher](cache.size) + lruCache, err := lru.NewWithEvict[LabelMatcher, *labels.Matcher](cache.size, cache.onEvict) if err != nil { return nil, err } @@ -85,10 +85,17 @@ func (c *MatchersCache) GetOrSet(key LabelMatcher, newItem NewItemFunc) (*labels return v.(*labels.Matcher), nil } +func (c *MatchersCache) onEvict(_ LabelMatcher, _ *labels.Matcher) { + c.metrics.evicted.Inc() + c.metrics.numItems.Set(float64(c.cache.Len())) +} + type matcherCacheMetrics struct { requestsTotal prometheus.Counter hitsTotal prometheus.Counter numItems prometheus.Gauge + maxItems prometheus.Gauge + evicted prometheus.Counter } func newMatcherCacheMetrics(reg prometheus.Registerer) *matcherCacheMetrics { @@ -105,5 +112,13 @@ func newMatcherCacheMetrics(reg prometheus.Registerer) *matcherCacheMetrics { Name: "thanos_matchers_cache_items", Help: "Total number of cached items", }), + maxItems: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ + Name: "thanos_matchers_cache_max_items", + Help: "Maximum number of items that can be cached", + }), + evicted: promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_matchers_cache_evicted_total", + Help: "Total number of items evicted from the cache", + }), } } diff --git a/pkg/store/storepb/matcher_cache_test.go b/pkg/store/storepb/matcher_cache_test.go index 754379474c..c76b942ae5 100644 --- a/pkg/store/storepb/matcher_cache_test.go +++ b/pkg/store/storepb/matcher_cache_test.go @@ -84,3 +84,32 @@ func TestMatchersCache(t *testing.T) { testutil.Equals(t, false, cacheHit) testutil.Equals(t, expected2.String(), item.String()) } + +func BenchmarkMatchersCache(b *testing.B) { + cache, err := storepb.NewMatchersCache(storepb.WithSize(100)) + if err != nil { + b.Fatalf("failed to create cache: %v", err) + } + + matchers := []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "key1", Value: "val1"}, + {Type: storepb.LabelMatcher_EQ, Name: "key2", Value: "val2"}, + {Type: storepb.LabelMatcher_EQ, Name: "key3", Value: "val3"}, + {Type: storepb.LabelMatcher_EQ, Name: "key4", Value: "val4"}, + {Type: storepb.LabelMatcher_RE, Name: "key5", Value: "^(val5|val6|val7|val8|val9).*$"}, + } + + newItem := func(matcher storepb.LabelMatcher) (*labels.Matcher, error) { + return storepb.MatcherToPromMatcher(matcher) + } + + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + matcher := matchers[i%len(matchers)] + _, err := cache.GetOrSet(matcher, newItem) + if err != nil { + b.Fatalf("failed to get or set cache item: %v", err) + } + } +}