Skip to content

Commit 2e1700e

Browse files
authored
Implement regex matcher cache on Store gateway: (#6491)
* Implement regex matcher cache on SG Signed-off-by: alanprot <[email protected]> * changelog Signed-off-by: alanprot <[email protected]> * lint Signed-off-by: alanprot <[email protected]> --------- Signed-off-by: alanprot <[email protected]>
1 parent bf8af36 commit 2e1700e

File tree

11 files changed

+128
-112
lines changed

11 files changed

+128
-112
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* [FEATURE] Ruler: Add support for per-user external labels #6340
2222
* [FEATURE] Query Frontend: Support a metadata federated query when `-tenant-federation.enabled=true`. #6461
2323
* [FEATURE] Query Frontend: Support an exemplar federated query when `-tenant-federation.enabled=true`. #6455
24-
* [FEATURE] Ingester: Add support for cache query matchers via `-ingester.matchers-cache-max-items. #6477
24+
* [FEATURE] Ingester/StoreGateway: Add support for cache regex query matchers via `-ingester.matchers-cache-max-items` and `-blocks-storage.bucket-store.matchers-cache-max-items`. #6477 #6491
2525
* [ENHANCEMENT] Querier: Add a `-tenant-federation.max-concurrent` flags to configure the number of worker processing federated query and add a `cortex_querier_federated_tenants_per_query` histogram to track the number of tenants per query. #6449
2626
* [ENHANCEMENT] Query Frontend: Add a number of series in the query response to the query stat log. #6423
2727
* [ENHANCEMENT] Store Gateway: Add a hedged request to reduce the tail latency. #6388

docs/blocks-storage/querier.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,10 @@ blocks_storage:
13411341
# CLI flag: -blocks-storage.bucket-store.metadata-cache.bucket-index-max-size-bytes
13421342
[bucket_index_max_size_bytes: <int> | default = 1048576]
13431343

1344+
# Maximum number of entries in the regex matchers cache. 0 to disable.
1345+
# CLI flag: -blocks-storage.bucket-store.matchers-cache-max-items
1346+
[matchers_cache_max_items: <int> | default = 0]
1347+
13441348
# Duration after which the blocks marked for deletion will be filtered out
13451349
# while fetching blocks. The idea of ignore-deletion-marks-delay is to
13461350
# ignore blocks that are marked for deletion with some delay. This ensures

docs/blocks-storage/store-gateway.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,10 @@ blocks_storage:
14451445
# CLI flag: -blocks-storage.bucket-store.metadata-cache.bucket-index-max-size-bytes
14461446
[bucket_index_max_size_bytes: <int> | default = 1048576]
14471447

1448+
# Maximum number of entries in the regex matchers cache. 0 to disable.
1449+
# CLI flag: -blocks-storage.bucket-store.matchers-cache-max-items
1450+
[matchers_cache_max_items: <int> | default = 0]
1451+
14481452
# Duration after which the blocks marked for deletion will be filtered out
14491453
# while fetching blocks. The idea of ignore-deletion-marks-delay is to
14501454
# ignore blocks that are marked for deletion with some delay. This ensures

docs/configuration/config-file-reference.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,10 @@ bucket_store:
18791879
# CLI flag: -blocks-storage.bucket-store.metadata-cache.bucket-index-max-size-bytes
18801880
[bucket_index_max_size_bytes: <int> | default = 1048576]
18811881

1882+
# Maximum number of entries in the regex matchers cache. 0 to disable.
1883+
# CLI flag: -blocks-storage.bucket-store.matchers-cache-max-items
1884+
[matchers_cache_max_items: <int> | default = 0]
1885+
18821886
# Duration after which the blocks marked for deletion will be filtered out
18831887
# while fetching blocks. The idea of ignore-deletion-marks-delay is to ignore
18841888
# blocks that are marked for deletion with some delay. This ensures store can
@@ -3182,7 +3186,7 @@ instance_limits:
31823186
# CLI flag: -ingester.disable-chunk-trimming
31833187
[disable_chunk_trimming: <boolean> | default = false]
31843188
3185-
# Maximum number of entries in the matchers cache. 0 to disable.
3189+
# Maximum number of entries in the regex matchers cache. 0 to disable.
31863190
# CLI flag: -ingester.matchers-cache-max-items
31873191
[matchers_cache_max_items: <int> | default = 0]
31883192
```

pkg/ingester/ingester.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
177177
f.BoolVar(&cfg.LabelsStringInterningEnabled, "ingester.labels-string-interning-enabled", false, "Experimental: Enable string interning for metrics labels.")
178178

179179
f.BoolVar(&cfg.DisableChunkTrimming, "ingester.disable-chunk-trimming", false, "Disable trimming of matching series chunks based on query Start and End time. When disabled, the result may contain samples outside the queried time range but select performances may be improved. Note that certain query results might change by changing this option.")
180-
f.IntVar(&cfg.MatchersCacheMaxItems, "ingester.matchers-cache-max-items", 0, "Maximum number of entries in the matchers cache. 0 to disable.")
180+
f.IntVar(&cfg.MatchersCacheMaxItems, "ingester.matchers-cache-max-items", 0, "Maximum number of entries in the regex matchers cache. 0 to disable.")
181181
}
182182

183183
func (cfg *Config) Validate() error {
@@ -719,7 +719,7 @@ func New(cfg Config, limits *validation.Overrides, registerer prometheus.Registe
719719

720720
if cfg.MatchersCacheMaxItems > 0 {
721721
r := prometheus.NewRegistry()
722-
registerer.MustRegister(newMatchCacheMetrics(r, logger))
722+
registerer.MustRegister(cortex_tsdb.NewMatchCacheMetrics("cortex_ingester", r, logger))
723723
i.matchersCache, err = storecache.NewMatchersCache(storecache.WithSize(cfg.MatchersCacheMaxItems), storecache.WithPromRegistry(r))
724724
if err != nil {
725725
return nil, err

pkg/ingester/ingester_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,21 @@ func TestMatcherCache(t *testing.T) {
159159
}
160160

161161
require.NoError(t, testutil.GatherAndCompare(registry, bytes.NewBufferString(fmt.Sprintf(`
162-
# HELP ingester_matchers_cache_evicted_total Total number of items evicted from the cache
163-
# TYPE ingester_matchers_cache_evicted_total counter
164-
ingester_matchers_cache_evicted_total 1
165-
# HELP ingester_matchers_cache_hits_total Total number of cache hits for series matchers
166-
# TYPE ingester_matchers_cache_hits_total counter
167-
ingester_matchers_cache_hits_total %v
168-
# HELP ingester_matchers_cache_items Total number of cached items
169-
# TYPE ingester_matchers_cache_items gauge
170-
ingester_matchers_cache_items %v
171-
# HELP ingester_matchers_cache_max_items Maximum number of items that can be cached
172-
# TYPE ingester_matchers_cache_max_items gauge
173-
ingester_matchers_cache_max_items 50
174-
# HELP ingester_matchers_cache_requests_total Total number of cache requests for series matchers
175-
# TYPE ingester_matchers_cache_requests_total counter
176-
ingester_matchers_cache_requests_total %v
162+
# HELP cortex_ingester_matchers_cache_evicted_total Total number of items evicted from the cache
163+
# TYPE cortex_ingester_matchers_cache_evicted_total counter
164+
cortex_ingester_matchers_cache_evicted_total 1
165+
# HELP cortex_ingester_matchers_cache_hits_total Total number of cache hits for series matchers
166+
# TYPE cortex_ingester_matchers_cache_hits_total counter
167+
cortex_ingester_matchers_cache_hits_total %v
168+
# HELP cortex_ingester_matchers_cache_items Total number of cached items
169+
# TYPE cortex_ingester_matchers_cache_items gauge
170+
cortex_ingester_matchers_cache_items %v
171+
# HELP cortex_ingester_matchers_cache_max_items Maximum number of items that can be cached
172+
# TYPE cortex_ingester_matchers_cache_max_items gauge
173+
cortex_ingester_matchers_cache_max_items 50
174+
# HELP cortex_ingester_matchers_cache_requests_total Total number of cache requests for series matchers
175+
# TYPE cortex_ingester_matchers_cache_requests_total counter
176+
cortex_ingester_matchers_cache_requests_total %v
177177
`, callPerMatcher*numberOfDifferentMatchers-numberOfDifferentMatchers, cfg.MatchersCacheMaxItems, callPerMatcher*numberOfDifferentMatchers)), "ingester_matchers_cache_requests_total", "ingester_matchers_cache_hits_total", "ingester_matchers_cache_items", "ingester_matchers_cache_max_items", "ingester_matchers_cache_evicted_total"))
178178
}
179179

pkg/ingester/metrics.go

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package ingester
22

33
import (
4-
"github.com/go-kit/log"
5-
"github.com/go-kit/log/level"
64
"github.com/prometheus/client_golang/prometheus"
75
"github.com/prometheus/client_golang/prometheus/promauto"
86

@@ -678,71 +676,3 @@ func (sm *tsdbMetrics) setRegistryForUser(userID string, registry *prometheus.Re
678676
func (sm *tsdbMetrics) removeRegistryForUser(userID string) {
679677
sm.regs.RemoveUserRegistry(userID, false)
680678
}
681-
682-
type matcherCacheMetrics struct {
683-
r *prometheus.Registry
684-
logger log.Logger
685-
686-
requestsTotal *prometheus.Desc
687-
hitsTotal *prometheus.Desc
688-
numItems *prometheus.Desc
689-
maxItems *prometheus.Desc
690-
evicted *prometheus.Desc
691-
}
692-
693-
func newMatchCacheMetrics(r *prometheus.Registry, l log.Logger) *matcherCacheMetrics {
694-
m := &matcherCacheMetrics{
695-
r: r,
696-
logger: l,
697-
requestsTotal: prometheus.NewDesc(
698-
"ingester_matchers_cache_requests_total",
699-
"Total number of cache requests for series matchers",
700-
nil, nil),
701-
hitsTotal: prometheus.NewDesc(
702-
"ingester_matchers_cache_hits_total",
703-
"Total number of cache hits for series matchers",
704-
nil, nil),
705-
numItems: prometheus.NewDesc(
706-
"ingester_matchers_cache_items",
707-
"Total number of cached items",
708-
nil, nil),
709-
maxItems: prometheus.NewDesc(
710-
"ingester_matchers_cache_max_items",
711-
"Maximum number of items that can be cached",
712-
nil, nil),
713-
evicted: prometheus.NewDesc(
714-
"ingester_matchers_cache_evicted_total",
715-
"Total number of items evicted from the cache",
716-
nil, nil),
717-
}
718-
return m
719-
}
720-
721-
func (m *matcherCacheMetrics) Describe(out chan<- *prometheus.Desc) {
722-
out <- m.requestsTotal
723-
out <- m.hitsTotal
724-
out <- m.numItems
725-
out <- m.maxItems
726-
out <- m.evicted
727-
}
728-
729-
func (m *matcherCacheMetrics) Collect(out chan<- prometheus.Metric) {
730-
gm, err := m.r.Gather()
731-
if err != nil {
732-
level.Warn(m.logger).Log("msg", "failed to gather metrics from registry", "err", err)
733-
return
734-
}
735-
736-
mfm, err := util.NewMetricFamilyMap(gm)
737-
738-
if err != nil {
739-
level.Warn(m.logger).Log("msg", "failed to create metric family map", "err", err)
740-
return
741-
}
742-
743-
out <- prometheus.MustNewConstMetric(m.requestsTotal, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_requests_total"))
744-
out <- prometheus.MustNewConstMetric(m.hitsTotal, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_hits_total"))
745-
out <- prometheus.MustNewConstMetric(m.numItems, prometheus.GaugeValue, mfm.SumGauges("thanos_matchers_cache_items"))
746-
out <- prometheus.MustNewConstMetric(m.maxItems, prometheus.GaugeValue, mfm.SumGauges("thanos_matchers_cache_max_items"))
747-
out <- prometheus.MustNewConstMetric(m.evicted, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_evicted_total"))
748-
}

pkg/storage/tsdb/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ type BucketStoreConfig struct {
275275
IndexCache IndexCacheConfig `yaml:"index_cache"`
276276
ChunksCache ChunksCacheConfig `yaml:"chunks_cache"`
277277
MetadataCache MetadataCacheConfig `yaml:"metadata_cache"`
278+
MatchersCacheMaxItems int `yaml:"matchers_cache_max_items"`
278279
IgnoreDeletionMarksDelay time.Duration `yaml:"ignore_deletion_mark_delay"`
279280
IgnoreBlocksWithin time.Duration `yaml:"ignore_blocks_within"`
280281
BucketIndex BucketIndexConfig `yaml:"bucket_index"`
@@ -373,6 +374,7 @@ func (cfg *BucketStoreConfig) RegisterFlags(f *flag.FlagSet) {
373374
f.Float64Var(&cfg.TokenBucketBytesLimiter.TouchedSeriesTokenFactor, "blocks-storage.bucket-store.token-bucket-bytes-limiter.touched-series-token-factor", 25, "Multiplication factor used for touched series token")
374375
f.Float64Var(&cfg.TokenBucketBytesLimiter.FetchedChunksTokenFactor, "blocks-storage.bucket-store.token-bucket-bytes-limiter.fetched-chunks-token-factor", 0, "Multiplication factor used for fetched chunks token")
375376
f.Float64Var(&cfg.TokenBucketBytesLimiter.TouchedChunksTokenFactor, "blocks-storage.bucket-store.token-bucket-bytes-limiter.touched-chunks-token-factor", 1, "Multiplication factor used for touched chunks token")
377+
f.IntVar(&cfg.MatchersCacheMaxItems, "blocks-storage.bucket-store.matchers-cache-max-items", 0, "Maximum number of entries in the regex matchers cache. 0 to disable.")
376378
}
377379

378380
// Validate the config.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package tsdb
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/go-kit/log"
7+
"github.com/go-kit/log/level"
8+
"github.com/prometheus/client_golang/prometheus"
9+
10+
"github.com/cortexproject/cortex/pkg/util"
11+
)
12+
13+
type MatcherCacheMetrics struct {
14+
r *prometheus.Registry
15+
logger log.Logger
16+
17+
requestsTotal *prometheus.Desc
18+
hitsTotal *prometheus.Desc
19+
numItems *prometheus.Desc
20+
maxItems *prometheus.Desc
21+
evicted *prometheus.Desc
22+
}
23+
24+
func NewMatchCacheMetrics(prefix string, r *prometheus.Registry, l log.Logger) *MatcherCacheMetrics {
25+
m := &MatcherCacheMetrics{
26+
r: r,
27+
logger: l,
28+
requestsTotal: prometheus.NewDesc(
29+
fmt.Sprintf("%v_matchers_cache_requests_total", prefix),
30+
"Total number of cache requests for series matchers",
31+
nil, nil),
32+
hitsTotal: prometheus.NewDesc(
33+
fmt.Sprintf("%v_matchers_cache_hits_total", prefix),
34+
"Total number of cache hits for series matchers",
35+
nil, nil),
36+
numItems: prometheus.NewDesc(
37+
fmt.Sprintf("%v_matchers_cache_items", prefix),
38+
"Total number of cached items",
39+
nil, nil),
40+
maxItems: prometheus.NewDesc(
41+
fmt.Sprintf("%v_matchers_cache_max_items", prefix),
42+
"Maximum number of items that can be cached",
43+
nil, nil),
44+
evicted: prometheus.NewDesc(
45+
fmt.Sprintf("%v_matchers_cache_evicted_total", prefix),
46+
"Total number of items evicted from the cache",
47+
nil, nil),
48+
}
49+
return m
50+
}
51+
52+
func (m *MatcherCacheMetrics) Describe(out chan<- *prometheus.Desc) {
53+
out <- m.requestsTotal
54+
out <- m.hitsTotal
55+
out <- m.numItems
56+
out <- m.maxItems
57+
out <- m.evicted
58+
}
59+
60+
func (m *MatcherCacheMetrics) Collect(out chan<- prometheus.Metric) {
61+
gm, err := m.r.Gather()
62+
if err != nil {
63+
level.Warn(m.logger).Log("msg", "failed to gather metrics from registry", "err", err)
64+
return
65+
}
66+
67+
mfm, err := util.NewMetricFamilyMap(gm)
68+
69+
if err != nil {
70+
level.Warn(m.logger).Log("msg", "failed to create metric family map", "err", err)
71+
return
72+
}
73+
74+
out <- prometheus.MustNewConstMetric(m.requestsTotal, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_requests_total"))
75+
out <- prometheus.MustNewConstMetric(m.hitsTotal, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_hits_total"))
76+
out <- prometheus.MustNewConstMetric(m.numItems, prometheus.GaugeValue, mfm.SumGauges("thanos_matchers_cache_items"))
77+
out <- prometheus.MustNewConstMetric(m.maxItems, prometheus.GaugeValue, mfm.SumGauges("thanos_matchers_cache_max_items"))
78+
out <- prometheus.MustNewConstMetric(m.evicted, prometheus.CounterValue, mfm.SumCounters("thanos_matchers_cache_evicted_total"))
79+
}

pkg/storegateway/bucket_stores.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ type BucketStores struct {
5656
// Index cache shared across all tenants.
5757
indexCache storecache.IndexCache
5858

59+
// Matchers cache shared across all tenants
60+
matcherCache storecache.MatchersCache
61+
5962
// Chunks bytes pool shared across all tenants.
6063
chunksPool pool.Pool[byte]
6164

@@ -140,6 +143,17 @@ func NewBucketStores(cfg tsdb.BlocksStorageConfig, shardingStrategy ShardingStra
140143
}),
141144
}
142145

146+
u.matcherCache = storecache.NoopMatchersCache
147+
148+
if cfg.BucketStore.MatchersCacheMaxItems > 0 {
149+
r := prometheus.NewRegistry()
150+
reg.MustRegister(tsdb.NewMatchCacheMetrics("cortex_storegateway", r, logger))
151+
u.matcherCache, err = storecache.NewMatchersCache(storecache.WithSize(cfg.BucketStore.MatchersCacheMaxItems), storecache.WithPromRegistry(r))
152+
if err != nil {
153+
return nil, err
154+
}
155+
}
156+
143157
// Init the index cache.
144158
if u.indexCache, err = tsdb.NewIndexCache(cfg.BucketStore.IndexCache, logger, reg); err != nil {
145159
return nil, errors.Wrap(err, "create index cache")
@@ -600,8 +614,10 @@ func (u *BucketStores) getOrCreateStore(userID string) (*store.BucketStore, erro
600614
}
601615

602616
bucketStoreReg := prometheus.NewRegistry()
617+
603618
bucketStoreOpts := []store.BucketStoreOption{
604619
store.WithLogger(userLogger),
620+
store.WithMatchersCache(u.matcherCache),
605621
store.WithRequestLoggerFunc(func(ctx context.Context, logger log.Logger) log.Logger {
606622
return util_log.HeadersFromContext(ctx, logger)
607623
}),

pkg/util/matchers.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)