Fix LabelValueStats in posting stats (#12342)

Problem:
LabelValueStats - This will provide a list of the label names and memory used in bytes.
It is calculated by adding the length of all values for a given label name.
But internally Prometheus stores the name and the value independently for each series.

Solution:
MemPostings struct maintains the values to seriesRef map which is used
to get the number of series which contains the label values.
Using that LabelValueStats is calculated as: seriesCnt * len(value
name)

Signed-off-by: Baskar Shanmugam <baskar.shanmugam.career@gmail.com>
This commit is contained in:
Baskar Shanmugam 2023-05-19 13:06:30 +05:30 committed by GitHub
parent e53478a08d
commit f731a90a7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 2 deletions

View file

@ -184,8 +184,9 @@ func (p *MemPostings) Stats(label string) *PostingsStats {
if n == label { if n == label {
metrics.push(Stat{Name: name, Count: uint64(len(values))}) metrics.push(Stat{Name: name, Count: uint64(len(values))})
} }
labelValuePairs.push(Stat{Name: n + "=" + name, Count: uint64(len(values))}) seriesCnt := uint64(len(values))
size += uint64(len(name)) labelValuePairs.push(Stat{Name: n + "=" + name, Count: seriesCnt})
size += uint64(len(name)) * seriesCnt
} }
labelValueLength.push(Stat{Name: n, Count: size}) labelValueLength.push(Stat{Name: n, Count: size})
} }

View file

@ -916,6 +916,35 @@ func BenchmarkPostings_Stats(b *testing.B) {
} }
} }
func TestMemPostingsStats(t *testing.T) {
// create a new MemPostings
p := NewMemPostings()
// add some postings to the MemPostings
p.Add(1, labels.FromStrings("label", "value1"))
p.Add(1, labels.FromStrings("label", "value2"))
p.Add(1, labels.FromStrings("label", "value3"))
p.Add(2, labels.FromStrings("label", "value1"))
// call the Stats method to calculate the cardinality statistics
stats := p.Stats("label")
// assert that the expected statistics were calculated
require.Equal(t, uint64(2), stats.CardinalityMetricsStats[0].Count)
require.Equal(t, "value1", stats.CardinalityMetricsStats[0].Name)
require.Equal(t, uint64(3), stats.CardinalityLabelStats[0].Count)
require.Equal(t, "label", stats.CardinalityLabelStats[0].Name)
require.Equal(t, uint64(24), stats.LabelValueStats[0].Count)
require.Equal(t, "label", stats.LabelValueStats[0].Name)
require.Equal(t, uint64(2), stats.LabelValuePairsStats[0].Count)
require.Equal(t, "label=value1", stats.LabelValuePairsStats[0].Name)
require.Equal(t, 3, stats.NumLabelPairs)
}
func TestMemPostings_Delete(t *testing.T) { func TestMemPostings_Delete(t *testing.T) {
p := NewMemPostings() p := NewMemPostings()
p.Add(1, labels.FromStrings("lbl1", "a")) p.Add(1, labels.FromStrings("lbl1", "a"))