Skip to content

Commit d519e78

Browse files
authored
Add reason why the key was evicted in the cortex_ingester_expanded_postings_cache_evicts metric (#6318)
* Enhancing metric Signed-off-by: alanprot <[email protected]> * lint Signed-off-by: alanprot <[email protected]> --------- Signed-off-by: alanprot <[email protected]>
1 parent 20686ac commit d519e78

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

pkg/storage/tsdb/expanded_postings_cache.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func NewPostingCacheMetrics(r prometheus.Registerer) *ExpandedPostingsCacheMetri
5555
CacheEvicts: promauto.With(r).NewCounterVec(prometheus.CounterOpts{
5656
Name: "cortex_ingester_expanded_postings_cache_evicts",
5757
Help: "Total number of evictions in the cache, excluding items that got evicted due to TTL.",
58-
}, []string{"cache"}),
58+
}, []string{"cache", "reason"}),
5959
NonCacheableQueries: promauto.With(r).NewCounterVec(prometheus.CounterOpts{
6060
Name: "cortex_ingester_expanded_postings_non_cacheable_queries",
6161
Help: "Total number of non cacheable queries.",
@@ -301,14 +301,15 @@ func (c *fifoCache[V]) expire() {
301301
return
302302
}
303303
c.cachedMtx.RLock()
304-
if !c.shouldEvictHead() {
304+
if _, r := c.shouldEvictHead(); !r {
305305
c.cachedMtx.RUnlock()
306306
return
307307
}
308308
c.cachedMtx.RUnlock()
309309
c.cachedMtx.Lock()
310310
defer c.cachedMtx.Unlock()
311-
for c.shouldEvictHead() {
311+
for reason, r := c.shouldEvictHead(); r; reason, r = c.shouldEvictHead() {
312+
c.metrics.CacheEvicts.WithLabelValues(c.name, reason).Inc()
312313
c.evictHead()
313314
}
314315
}
@@ -340,6 +341,7 @@ func (c *fifoCache[V]) getPromiseForKey(k string, fetch func() (V, int64, error)
340341

341342
// If is cached but is expired, lets try to replace the cache value.
342343
if loaded.(*cacheEntryPromise[V]).isExpired(c.cfg.Ttl, c.timeNow()) && c.cachedValues.CompareAndSwap(k, loaded, r) {
344+
c.metrics.CacheEvicts.WithLabelValues(c.name, "expired").Inc()
343345
r.v, r.sizeBytes, r.err = fetch()
344346
r.sizeBytes += int64(len(k))
345347
c.updateSize(loaded.(*cacheEntryPromise[V]).sizeBytes, r.sizeBytes)
@@ -357,22 +359,25 @@ func (c *fifoCache[V]) contains(k string) bool {
357359
return ok
358360
}
359361

360-
func (c *fifoCache[V]) shouldEvictHead() bool {
361-
if c.cachedBytes > c.cfg.MaxBytes {
362-
c.metrics.CacheEvicts.WithLabelValues(c.name).Inc()
363-
return true
364-
}
362+
func (c *fifoCache[V]) shouldEvictHead() (string, bool) {
365363
h := c.cached.Front()
366364
if h == nil {
367-
return false
365+
return "", false
368366
}
367+
368+
if c.cachedBytes > c.cfg.MaxBytes {
369+
return "full", true
370+
}
371+
369372
key := h.Value.(string)
370373

371374
if l, ok := c.cachedValues.Load(key); ok {
372-
return l.(*cacheEntryPromise[V]).isExpired(c.cfg.Ttl, c.timeNow())
375+
if l.(*cacheEntryPromise[V]).isExpired(c.cfg.Ttl, c.timeNow()) {
376+
return "expired", true
377+
}
373378
}
374379

375-
return false
380+
return "", false
376381
}
377382

378383
func (c *fifoCache[V]) evictHead() {

pkg/storage/tsdb/expanded_postings_cache_test.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package tsdb
22

33
import (
4+
"bytes"
45
"fmt"
56
"strings"
67
"sync"
78
"testing"
89
"time"
910

1011
"github.com/prometheus/client_golang/prometheus"
12+
"github.com/prometheus/client_golang/prometheus/testutil"
1113
"github.com/stretchr/testify/require"
1214
"go.uber.org/atomic"
1315
)
@@ -88,7 +90,8 @@ func TestFifoCacheExpire(t *testing.T) {
8890

8991
for name, c := range tc {
9092
t.Run(name, func(t *testing.T) {
91-
m := NewPostingCacheMetrics(prometheus.NewPedanticRegistry())
93+
r := prometheus.NewPedanticRegistry()
94+
m := NewPostingCacheMetrics(r)
9295
timeNow := time.Now
9396
cache := newFifoCache[int](c.cfg, "test", m, timeNow)
9497

@@ -118,6 +121,16 @@ func TestFifoCacheExpire(t *testing.T) {
118121

119122
require.Equal(t, c.expectedFinalItems, totalCacheSize)
120123

124+
if c.expectedFinalItems != numberOfKeys {
125+
err := testutil.GatherAndCompare(r, bytes.NewBufferString(fmt.Sprintf(`
126+
# HELP cortex_ingester_expanded_postings_cache_evicts Total number of evictions in the cache, excluding items that got evicted due to TTL.
127+
# TYPE cortex_ingester_expanded_postings_cache_evicts counter
128+
cortex_ingester_expanded_postings_cache_evicts{cache="test",reason="full"} %v
129+
`, numberOfKeys-c.expectedFinalItems)), "cortex_ingester_expanded_postings_cache_evicts")
130+
require.NoError(t, err)
131+
132+
}
133+
121134
if c.ttlExpire {
122135
cache.timeNow = func() time.Time {
123136
return timeNow().Add(2 * c.cfg.Ttl)
@@ -135,6 +148,29 @@ func TestFifoCacheExpire(t *testing.T) {
135148
// Total Size Updated
136149
require.Equal(t, originalSize+10, cache.cachedBytes)
137150
}
151+
152+
err := testutil.GatherAndCompare(r, bytes.NewBufferString(fmt.Sprintf(`
153+
# HELP cortex_ingester_expanded_postings_cache_evicts Total number of evictions in the cache, excluding items that got evicted due to TTL.
154+
# TYPE cortex_ingester_expanded_postings_cache_evicts counter
155+
cortex_ingester_expanded_postings_cache_evicts{cache="test",reason="expired"} %v
156+
`, numberOfKeys)), "cortex_ingester_expanded_postings_cache_evicts")
157+
require.NoError(t, err)
158+
159+
cache.timeNow = func() time.Time {
160+
return timeNow().Add(5 * c.cfg.Ttl)
161+
}
162+
163+
cache.getPromiseForKey("newKwy", func() (int, int64, error) {
164+
return 2, 18, nil
165+
})
166+
167+
// Should expire all keys again as ttl is expired
168+
err = testutil.GatherAndCompare(r, bytes.NewBufferString(fmt.Sprintf(`
169+
# HELP cortex_ingester_expanded_postings_cache_evicts Total number of evictions in the cache, excluding items that got evicted due to TTL.
170+
# TYPE cortex_ingester_expanded_postings_cache_evicts counter
171+
cortex_ingester_expanded_postings_cache_evicts{cache="test",reason="expired"} %v
172+
`, numberOfKeys*2)), "cortex_ingester_expanded_postings_cache_evicts")
173+
require.NoError(t, err)
138174
}
139175
})
140176
}

0 commit comments

Comments
 (0)