Skip to content

Commit 223bbd9

Browse files
ZhengYa-0110SongZhen0704
authored andcommitted
feat: instead string to id in prometheus label cache
1 parent 2d3fa39 commit 223bbd9

7 files changed

Lines changed: 257 additions & 78 deletions

File tree

server/controller/prometheus/cache/cache.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,16 @@ func newCache(orgID int) (*Cache, error) {
5858
}
5959
log.Infof("new prometheus cache", org.LogPrefix)
6060
mn := newMetricName(org)
61+
ln := newLabelName(org)
62+
lv := newLabelValue(org)
6163
c := &Cache{
6264
org: org,
6365
canRefresh: make(chan bool, 1),
6466
MetricName: mn,
65-
LabelName: newLabelName(org),
66-
LabelValue: newLabelValue(org),
67+
LabelName: ln,
68+
LabelValue: lv,
6769
MetricAndAPPLabelLayout: newMetricAndAPPLabelLayout(org),
68-
Label: newLabel(org),
70+
Label: newLabel(org, ln, lv),
6971
}
7072
c.canRefresh <- true
7173
return c, nil
@@ -93,13 +95,17 @@ LOOP:
9395

9496
func (c *Cache) refresh() error {
9597
log.Infof("refresh cache started", c.org.LogPrefix)
98+
// LabelName and LabelValue must be refreshed before Label,
99+
// because Label.refresh() converts name/value strings to IDs.
96100
egRunAhead := &errgroup.Group{}
97101
common.AppendErrGroup(egRunAhead, c.MetricName.refresh)
98-
common.AppendErrGroup(egRunAhead, c.Label.refresh)
99-
egRunAhead.Wait()
102+
common.AppendErrGroup(egRunAhead, c.LabelName.refresh)
103+
common.AppendErrGroup(egRunAhead, c.LabelValue.refresh)
104+
if err := egRunAhead.Wait(); err != nil {
105+
return err
106+
}
100107
eg := &errgroup.Group{}
101-
common.AppendErrGroup(eg, c.LabelName.refresh)
102-
common.AppendErrGroup(eg, c.LabelValue.refresh)
108+
common.AppendErrGroup(eg, c.Label.refresh)
103109
common.AppendErrGroup(eg, c.MetricAndAPPLabelLayout.refresh)
104110
err := eg.Wait()
105111
log.Infof("refresh cache completed", c.org.LogPrefix)

server/controller/prometheus/cache/cache_test.go

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,38 @@ func generateMockDBLabelValues(size int) []*metadbmodel.PrometheusLabelValue {
133133
return mockData
134134
}
135135

136-
// newTestLabel 创建一个不依赖 DB 的 label 实例
136+
// newTestLabel 创建一个不依赖 DB 的 label 实例,同时创建配套的 labelName/labelValue
137137
func newTestLabel() *label {
138-
return newLabel(nil)
138+
ln := newTestLabelName()
139+
lv := newTestLabelValue()
140+
return newLabel(nil, ln, lv)
141+
}
142+
143+
// newTestLabelWithRefs 返回 label 及其内部引用的 labelName/labelValue
144+
func newTestLabelWithRefs() (*label, *labelName, *labelValue) {
145+
ln := newTestLabelName()
146+
lv := newTestLabelValue()
147+
l := newLabel(nil, ln, lv)
148+
return l, ln, lv
149+
}
150+
151+
// populateLabelDeps ensures labelName and labelValue contain entries matching
152+
// the naming pattern used by generateProtoLabels ("label_name_i" / "label_value_i").
153+
func populateLabelDeps(l *label, n int) {
154+
lnBatch := make([]*controller.PrometheusLabelName, n)
155+
lvBatch := make([]*controller.PrometheusLabelValue, n)
156+
for i := 0; i < n; i++ {
157+
lnBatch[i] = &controller.PrometheusLabelName{
158+
Name: proto.String(fmt.Sprintf("label_name_%d", i)),
159+
Id: proto.Uint32(uint32(i + 1)),
160+
}
161+
lvBatch[i] = &controller.PrometheusLabelValue{
162+
Value: proto.String(fmt.Sprintf("label_value_%d", i)),
163+
Id: proto.Uint32(uint32(i + 1)),
164+
}
165+
}
166+
l.labelName.Add(lnBatch)
167+
l.labelValue.Add(lvBatch)
139168
}
140169

141170
func newTestMetricName() *metricName {
@@ -161,10 +190,10 @@ func countLabelConcurrentMap(m map[LabelKey]int) int {
161190
return len(m)
162191
}
163192

164-
func buildLabelConcurrentMap(n int) map[LabelKey]int {
165-
m := make(map[LabelKey]int, n)
193+
func buildLabelConcurrentMap(n int) map[IDLabelKey]int {
194+
m := make(map[IDLabelKey]int, n)
166195
for i := 0; i < n; i++ {
167-
m[NewLabelKey(fmt.Sprintf("label_name_%d", i), fmt.Sprintf("label_value_%d", i))] = i + 1
196+
m[IDLabelKey{NameID: i + 1, ValueID: i + 1}] = i + 1
168197
}
169198
return m
170199
}
@@ -176,9 +205,9 @@ func buildLabelValueMap(n int) map[string]int {
176205
return m
177206
}
178207

179-
func resetLabelState(l *label, active map[LabelKey]int) {
208+
func resetLabelState(l *label, active map[IDLabelKey]int) {
180209
l.mu.Lock()
181-
l.pending = make(map[LabelKey]int)
210+
l.pending = make(map[IDLabelKey]int)
182211
l.mu.Unlock()
183212
l.replaceActive(active)
184213
}
@@ -268,7 +297,10 @@ func refreshLabelEntriesCurrent(l *label, entries []labelRefreshEntry) {
268297
l.mu.Lock()
269298
defer l.mu.Unlock()
270299
for _, entry := range entries {
271-
l.pending[entry.key] = entry.id
300+
idk, ok := l.toIDKey(entry.key)
301+
if ok {
302+
l.pending[idk] = entry.id
303+
}
272304
}
273305
}
274306
func refreshLabelValueEntriesCurrent(lv *labelValue, entries []labelValueRefreshEntry) {
@@ -326,6 +358,7 @@ func benchmarkProtoRefreshSizes() []int {
326358
func TestLabel_AddAndGet(t *testing.T) {
327359
l := newTestLabel()
328360
batch := generateProtoLabels(100)
361+
populateLabelDeps(l, 100)
329362

330363
l.Add(batch)
331364

@@ -401,6 +434,7 @@ func TestLayout_AddAndGet(t *testing.T) {
401434

402435
func TestLabel_GetKeyToID_SnapshotIsolation(t *testing.T) {
403436
l := newTestLabel()
437+
populateLabelDeps(l, 101)
404438
l.Add(generateProtoLabels(100))
405439

406440
// 取快照
@@ -411,6 +445,9 @@ func TestLabel_GetKeyToID_SnapshotIsolation(t *testing.T) {
411445
extra := []*controller.PrometheusLabel{
412446
{Name: proto.String("extra_name"), Value: proto.String("extra_value"), Id: proto.Uint32(999)},
413447
}
448+
// Populate deps for extra entry
449+
l.labelName.Add([]*controller.PrometheusLabelName{{Name: proto.String("extra_name"), Id: proto.Uint32(102)}})
450+
l.labelValue.Add([]*controller.PrometheusLabelValue{{Value: proto.String("extra_value"), Id: proto.Uint32(102)}})
414451
l.Add(extra)
415452

416453
// 快照不受影响
@@ -468,6 +505,7 @@ func TestLabelValue_GetValueToID_SnapshotIsolation(t *testing.T) {
468505

469506
func TestLabel_SnapshotSwap_DiscardsOldEntries(t *testing.T) {
470507
l := newTestLabel()
508+
populateLabelDeps(l, 200)
471509

472510
// 初始加载 200 条
473511
l.Add(generateProtoLabels(200))
@@ -516,6 +554,7 @@ func TestLabelValue_SnapshotSwap_DiscardsOldEntries(t *testing.T) {
516554

517555
func TestConcurrentLabel_ReadDuringSwap(t *testing.T) {
518556
l := newTestLabel()
557+
populateLabelDeps(l, 1000)
519558
l.Add(generateProtoLabels(1000))
520559

521560
const (
@@ -740,6 +779,7 @@ func TestConcurrentLayout_ReadDuringSwap(t *testing.T) {
740779

741780
func TestConcurrentLabel_SnapshotDuringSwap(t *testing.T) {
742781
l := newTestLabel()
782+
populateLabelDeps(l, 500)
743783
l.Add(generateProtoLabels(500))
744784

745785
var wg sync.WaitGroup
@@ -785,13 +825,14 @@ func TestLabel_LargeScale_MemoryRelease(t *testing.T) {
785825
const N = 1_000_000
786826

787827
l := newTestLabel()
828+
populateLabelDeps(l, N)
788829

789830
// 阶段1:加载百万条数据
790831
batch := make([]*controller.PrometheusLabel, N)
791832
for i := 0; i < N; i++ {
792833
batch[i] = &controller.PrometheusLabel{
793-
Name: proto.String(fmt.Sprintf("n_%d", i)),
794-
Value: proto.String(fmt.Sprintf("v_%d", i)),
834+
Name: proto.String(fmt.Sprintf("label_name_%d", i)),
835+
Value: proto.String(fmt.Sprintf("label_value_%d", i)),
795836
Id: proto.Uint32(uint32(i + 1)),
796837
}
797838
}
@@ -806,9 +847,9 @@ func TestLabel_LargeScale_MemoryRelease(t *testing.T) {
806847

807848
// 阶段2:模拟 refresh——只保留 10% 的数据(模拟 Cleaner 删除后 refresh)
808849
kept := N / 10
809-
newMap := make(map[LabelKey]int, kept)
850+
newMap := make(map[IDLabelKey]int, kept)
810851
for i := 0; i < kept; i++ {
811-
newMap[NewLabelKey(fmt.Sprintf("n_%d", i), fmt.Sprintf("v_%d", i))] = i + 1
852+
newMap[IDLabelKey{NameID: i + 1, ValueID: i + 1}] = i + 1
812853
}
813854
resetLabelState(l, newMap)
814855

@@ -893,6 +934,7 @@ func BenchmarkLabel_Add(b *testing.B) {
893934
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
894935
for i := 0; i < b.N; i++ {
895936
l := newTestLabel()
937+
populateLabelDeps(l, size)
896938
l.Add(batch)
897939
}
898940
})
@@ -902,6 +944,7 @@ func BenchmarkLabel_Add(b *testing.B) {
902944
func BenchmarkLabel_GetIDByKey(b *testing.B) {
903945
for _, size := range benchmarkLabelLookupSizes() {
904946
l := newTestLabel()
947+
populateLabelDeps(l, size)
905948
l.Add(generateProtoLabels(size))
906949
keys := generateLabelKeys(size)
907950

@@ -919,6 +962,7 @@ func BenchmarkLabel_GetIDByKey(b *testing.B) {
919962
func BenchmarkLabel_GetKeyToID_Snapshot(b *testing.B) {
920963
for _, size := range []int{1000, 10_000, 100_000} {
921964
l := newTestLabel()
965+
populateLabelDeps(l, size)
922966
l.Add(generateProtoLabels(size))
923967

924968
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
@@ -934,9 +978,9 @@ func BenchmarkLabel_SnapshotSwap(b *testing.B) {
934978
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
935979
l := newTestLabel()
936980
for i := 0; i < b.N; i++ {
937-
newMap := make(map[LabelKey]int, size)
981+
newMap := make(map[IDLabelKey]int, size)
938982
for j := 0; j < size; j++ {
939-
newMap[NewLabelKey(fmt.Sprintf("n_%d", j), fmt.Sprintf("v_%d", j))] = j + 1
983+
newMap[IDLabelKey{NameID: j + 1, ValueID: j + 1}] = j + 1
940984
}
941985
resetLabelState(l, newMap)
942986
}
@@ -948,11 +992,13 @@ func BenchmarkLabel_Refresh(b *testing.B) {
948992
for _, size := range benchmarkRefreshSizes() {
949993
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
950994
l := newTestLabel()
951-
mockData := generateMockDBLabels(size)
995+
populateLabelDeps(l, size)
996+
batch := generateProtoLabels(size)
952997

953998
b.ResetTimer()
954999
for i := 0; i < b.N; i++ {
955-
l.processLoadedData(mockData)
1000+
l.Add(batch)
1001+
resetLabelState(l, make(map[IDLabelKey]int))
9561002
}
9571003
})
9581004
}
@@ -1062,6 +1108,16 @@ func BenchmarkLayout_GetIndexByKey(b *testing.B) {
10621108
func BenchmarkLabel_MixedReadWrite(b *testing.B) {
10631109
for _, size := range []int{10_000, 100_000} {
10641110
l := newTestLabel()
1111+
populateLabelDeps(l, size)
1112+
// Pre-populate deps for "hot" entries used in write path
1113+
hotLN := make([]*controller.PrometheusLabelName, 100)
1114+
hotLV := make([]*controller.PrometheusLabelValue, 100)
1115+
for i := 0; i < 100; i++ {
1116+
hotLN[i] = &controller.PrometheusLabelName{Name: proto.String(fmt.Sprintf("hot_%d", i)), Id: proto.Uint32(uint32(size + i + 1))}
1117+
hotLV[i] = &controller.PrometheusLabelValue{Value: proto.String(fmt.Sprintf("hot_v_%d", i)), Id: proto.Uint32(uint32(size + i + 1))}
1118+
}
1119+
l.labelName.Add(hotLN)
1120+
l.labelValue.Add(hotLV)
10651121
l.Add(generateProtoLabels(size))
10661122
keys := generateLabelKeys(size)
10671123

0 commit comments

Comments
 (0)