Merge pull request #19703 from roidelapluie/roidelapluie/scrape-remove-cache-hash

perf(scrape): remove unused series cache hashes
This commit is contained in:
Julien authored and GitHub committed 2026-09-16 11:00:51 +02:00
commit 50461b669f
3 files changed
+23 -28

No files matched your search

+6 -13
View File
@@ -920,7 +920,6 @@ type loop interface {
type cacheEntry struct {
ref storage.SeriesRef
lastIter uint64
hash uint64
lset labels.Labels
// st is an optional state for ST synthesis.
@@ -1116,8 +1115,8 @@ func (c *scrapeCache) get(met []byte) (*cacheEntry, bool, bool) {
return e, true, alreadyScraped
}
func (c *scrapeCache) addRef(met []byte, ref storage.SeriesRef, lset labels.Labels, hash uint64) (ce *cacheEntry) {
ce = &cacheEntry{ref: ref, lastIter: c.iter, lset: lset, hash: hash}
func (c *scrapeCache) addRef(met []byte, ref storage.SeriesRef, lset labels.Labels) (ce *cacheEntry) {
ce = &cacheEntry{ref: ref, lastIter: c.iter, lset: lset}
c.series[string(met)] = ce
return ce
}
@@ -1891,21 +1890,15 @@ loop:
continue
}
ce, seriesCached, seriesAlreadyScraped := sl.cache.get(met)
var (
ref storage.SeriesRef
hash uint64
)
var ref storage.SeriesRef
if seriesCached {
ref = ce.ref
lset = ce.lset
hash = ce.hash
} else {
p.Labels(&lset)
hash = lset.Hash()
// Hash label set as it is seen local to the target. Then add target labels
// and relabeling and store the final label set.
// Add target labels and apply relabeling before storing the final label set.
lset = sl.sampleMutator(lset)
// The label set may be set to empty to indicate dropping.
@@ -1986,7 +1979,7 @@ loop:
// If a series was new but we didn't append it due to sample_limit or other errors then we don't need
// it in the scrape cache because we don't need to emit StaleNaNs for it when it disappears.
if !seriesCached && sampleAdded {
ce = sl.cache.addRef(met, ref, lset, hash)
ce = sl.cache.addRef(met, ref, lset)
if ce != nil && ce.ref != 0 && (parsedTimestamp == nil || sl.trackTimestampsStaleness) {
// Bypass staleness logic if there is an explicit timestamp.
// But make sure we only do this if we have a cache entry (ce) for our series.
@@ -2396,7 +2389,7 @@ func (sl *scrapeLoopAppender) addReportSample(s reportSample, t int64, v float64
switch {
case err == nil:
if !ok {
sl.cache.addRef(s.name, ref, lset, lset.Hash())
sl.cache.addRef(s.name, ref, lset)
// We only need to add metadata once a scrape target appears.
if sl.appendMetadataToWAL {
if _, merr := sl.UpdateMetadata(ref, lset, s.Metadata); merr != nil {
+4 -10
View File
@@ -206,21 +206,15 @@ loop:
continue
}
ce, seriesCached, seriesAlreadyScraped := sl.cache.get(met)
var (
ref storage.SeriesRef
hash uint64
)
var ref storage.SeriesRef
if seriesCached {
ref = ce.ref
lset = ce.lset
hash = ce.hash
} else {
p.Labels(&lset)
hash = lset.Hash()
// Hash label set as it is seen local to the target. Then add target labels
// and relabeling and store the final label set.
// Add target labels and apply relabeling before storing the final label set.
lset = sl.sampleMutator(lset)
// The label set may be set to empty to indicate dropping.
@@ -344,7 +338,7 @@ loop:
// If a series was new, but we didn't append it due to sample_limit or other errors then we don't need
// it in the scrape cache because we don't need to emit StaleNaNs for it when it disappears.
if !seriesCached && sampleAdded {
ce = sl.cache.addRef(met, ref, lset, hash)
ce = sl.cache.addRef(met, ref, lset)
if sampleLimitErr == nil && bucketLimitErr == nil {
seriesAdded++
@@ -433,7 +427,7 @@ func (sl *scrapeLoopAppenderV2) addReportSample(s reportSample, t int64, v float
switch {
case err == nil:
if !ok {
sl.cache.addRef(s.name, ref, lset, lset.Hash())
sl.cache.addRef(s.name, ref, lset)
}
return nil
case errors.Is(err, storage.ErrOutOfOrderSample), errors.Is(err, storage.ErrDuplicateSampleForTimestamp):
+13 -5
View File
@@ -2654,7 +2654,11 @@ func BenchmarkScrapeLoopAppend(b *testing.B) {
{name: "PromProto", contentType: "application/vnd.google.protobuf", parsable: metricsProto},
} {
b.Run(fmt.Sprintf("fmt=%v", bcase.name), func(b *testing.B) {
benchScrapeLoopAppend(b, withStorage, appV2, bcase.parsable, bcase.contentType, appendMetadataToWAL, false, false, false)
for _, coldCache := range []bool{false, true} {
b.Run(fmt.Sprintf("coldCache=%v", coldCache), func(b *testing.B) {
benchScrapeLoopAppend(b, withStorage, appV2, bcase.parsable, bcase.contentType, appendMetadataToWAL, false, false, false, coldCache)
})
}
})
}
})
@@ -2680,7 +2684,7 @@ func BenchmarkScrapeLoopAppend_STSynthesis(b *testing.B) {
{name: "237FamsAllTypes", parsableText: readTextParseTestMetrics(b), contentType: "application/openmetrics-text", convertToNHCB: true}, // ~185.7 KB, ~70.6 KB in proto.
} {
b.Run(fmt.Sprintf("withStorage=%v/synthesizeST=%v/data=%v", withStorage, synthesizeST, data.name), func(b *testing.B) {
benchScrapeLoopAppend(b, withStorage, true, data.parsableText, data.contentType, false, false, synthesizeST, data.convertToNHCB)
benchScrapeLoopAppend(b, withStorage, true, data.parsableText, data.contentType, false, false, synthesizeST, data.convertToNHCB, false)
})
}
}
@@ -2697,6 +2701,7 @@ func benchScrapeLoopAppend(
enableExemplarStorage bool,
synthesizeST bool,
convertToNHCB bool,
coldCache bool,
) {
var a compatAppendable = teststorage.NewAppendable().SkipRecording(true) // Make it noop for benchmark purposes.
if withStorage {
@@ -2720,6 +2725,10 @@ func benchScrapeLoopAppend(
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
if coldCache {
// Model the first scrape of a target, before any series are cached.
sl.cache = newScrapeCache(sl.metrics)
}
app := sl.appender()
ts = ts.Add(time.Second)
_, _, _, err := app.append(parsable, contentType, ts)
@@ -2749,7 +2758,7 @@ func BenchmarkScrapeLoopAppend_HistogramsWithExemplars(b *testing.B) {
for _, appV2 := range []bool{false, true} {
b.Run(fmt.Sprintf("appV2=%v", appV2), func(b *testing.B) {
parsable := makeTestHistogramsWithExemplars(100) // ~255.8 KB in OM text.
benchScrapeLoopAppend(b, true, appV2, parsable, "application/openmetrics-text", false, true, false, false)
benchScrapeLoopAppend(b, true, appV2, parsable, "application/openmetrics-text", false, true, false, false, false)
})
}
}
@@ -3525,10 +3534,9 @@ func testScrapeLoopAppendCacheEntryButErrNotFound(t *testing.T, appV2 bool) {
_, err := p.Next()
require.NoError(t, err)
p.Labels(&lset)
hash := lset.Hash()
// Create a fake entry in the cache
sl.cache.addRef(metric, fakeRef, lset, hash)
sl.cache.addRef(metric, fakeRef, lset)
now := time.Now()
app := sl.appender()