Skip to content

Commit 11ae3ea

Browse files
committed
Store Prometheus labels as a slice instead of a map
This should be more efficient in general, and will let us skip target hashing completely in the future.
1 parent de89f7c commit 11ae3ea

13 files changed

+103
-98
lines changed

cmd/otel-allocator/allocation/allocator_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package allocation
1717
import (
1818
"testing"
1919

20-
"github.com/prometheus/common/model"
20+
"github.com/prometheus/prometheus/model/labels"
2121
"github.com/stretchr/testify/assert"
2222

2323
"github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/target"
@@ -176,11 +176,11 @@ func TestAllocationCollision(t *testing.T) {
176176

177177
cols := MakeNCollectors(3, 0)
178178
allocator.SetCollectors(cols)
179-
firstLabels := model.LabelSet{
180-
"test": "test1",
179+
firstLabels := labels.Labels{
180+
{Name: "test", Value: "test1"},
181181
}
182-
secondLabels := model.LabelSet{
183-
"test": "test2",
182+
secondLabels := labels.Labels{
183+
{Name: "test", Value: "test2"},
184184
}
185185
firstTarget := target.NewItem("sample-name", "0.0.0.0:8000", firstLabels, "")
186186
secondTarget := target.NewItem("sample-name", "0.0.0.0:8000", secondLabels, "")

cmd/otel-allocator/allocation/consistent_hashing.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package allocation
1616

1717
import (
1818
"fmt"
19-
"strings"
2019

2120
"github.com/buraksezer/consistent"
2221
"github.com/cespare/xxhash/v2"
@@ -59,7 +58,7 @@ func (s *consistentHashingStrategy) GetName() string {
5958
}
6059

6160
func (s *consistentHashingStrategy) GetCollectorForTarget(collectors map[string]*Collector, item *target.Item) (*Collector, error) {
62-
hashKey := strings.Join(item.TargetURL, "")
61+
hashKey := item.TargetURL
6362
member := s.consistentHasher.LocateKey([]byte(hashKey))
6463
collectorName := member.String()
6564
collector, ok := collectors[collectorName]

cmd/otel-allocator/allocation/per_node_test.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package allocation
1717
import (
1818
"testing"
1919

20-
"github.com/prometheus/common/model"
20+
"github.com/prometheus/prometheus/model/labels"
2121
"github.com/stretchr/testify/assert"
2222
logf "sigs.k8s.io/controller-runtime/pkg/log"
2323

@@ -33,23 +33,23 @@ func TestAllocationPerNode(t *testing.T) {
3333

3434
cols := MakeNCollectors(4, 0)
3535
s.SetCollectors(cols)
36-
firstLabels := model.LabelSet{
37-
"test": "test1",
38-
"__meta_kubernetes_pod_node_name": "node-0",
36+
firstLabels := labels.Labels{
37+
{Name: "test", Value: "test1"},
38+
{Name: "__meta_kubernetes_pod_node_name", Value: "node-0"},
3939
}
40-
secondLabels := model.LabelSet{
41-
"test": "test2",
42-
"__meta_kubernetes_node_name": "node-1",
40+
secondLabels := labels.Labels{
41+
{Name: "test", Value: "test2"},
42+
{Name: "__meta_kubernetes_node_name", Value: "node-1"},
4343
}
4444
// no label, should be skipped
45-
thirdLabels := model.LabelSet{
46-
"test": "test3",
45+
thirdLabels := labels.Labels{
46+
{Name: "test", Value: "test3"},
4747
}
4848
// endpointslice target kind and name
49-
fourthLabels := model.LabelSet{
50-
"test": "test4",
51-
"__meta_kubernetes_endpointslice_address_target_kind": "Node",
52-
"__meta_kubernetes_endpointslice_address_target_name": "node-3",
49+
fourthLabels := labels.Labels{
50+
{Name: "test", Value: "test4"},
51+
{Name: "__meta_kubernetes_endpointslice_address_target_kind", Value: "Node"},
52+
{Name: "__meta_kubernetes_endpointslice_address_target_name", Value: "node-3"},
5353
}
5454

5555
firstTarget := target.NewItem("sample-name", "0.0.0.0:8000", firstLabels, "")

cmd/otel-allocator/allocation/testutils.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"strconv"
2222
"testing"
2323

24-
"github.com/prometheus/common/model"
24+
"github.com/prometheus/prometheus/model/labels"
2525
"github.com/stretchr/testify/require"
2626
logf "sigs.k8s.io/controller-runtime/pkg/log"
2727

@@ -39,9 +39,9 @@ func MakeNNewTargets(n int, numCollectors int, startingIndex int) map[string]*ta
3939
toReturn := map[string]*target.Item{}
4040
for i := startingIndex; i < n+startingIndex; i++ {
4141
collector := fmt.Sprintf("collector-%d", colIndex(i, numCollectors))
42-
label := model.LabelSet{
43-
"i": model.LabelValue(strconv.Itoa(i)),
44-
"total": model.LabelValue(strconv.Itoa(n + startingIndex)),
42+
label := labels.Labels{
43+
{Name: "i", Value: strconv.Itoa(i)},
44+
{Name: "total", Value: strconv.Itoa(n + startingIndex)},
4545
}
4646
newTarget := target.NewItem(fmt.Sprintf("test-job-%d", i), fmt.Sprintf("test-url-%d", i), label, collector)
4747
toReturn[newTarget.Hash()] = newTarget
@@ -65,10 +65,10 @@ func MakeNCollectors(n int, startingIndex int) map[string]*Collector {
6565
func MakeNNewTargetsWithEmptyCollectors(n int, startingIndex int) map[string]*target.Item {
6666
toReturn := map[string]*target.Item{}
6767
for i := startingIndex; i < n+startingIndex; i++ {
68-
label := model.LabelSet{
69-
"i": model.LabelValue(strconv.Itoa(i)),
70-
"total": model.LabelValue(strconv.Itoa(n + startingIndex)),
71-
"__meta_kubernetes_pod_node_name": model.LabelValue("node-0"),
68+
label := labels.Labels{
69+
{Name: "i", Value: strconv.Itoa(i)},
70+
{Name: "total", Value: strconv.Itoa(n + startingIndex)},
71+
{Name: "__meta_kubernetes_pod_node_name", Value: "node-0"},
7272
}
7373
newTarget := target.NewItem(fmt.Sprintf("test-job-%d", i), fmt.Sprintf("test-url-%d", i), label, "")
7474
toReturn[newTarget.Hash()] = newTarget

cmd/otel-allocator/benchmark_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/prometheus/common/model"
2929
"github.com/prometheus/prometheus/discovery"
3030
"github.com/prometheus/prometheus/discovery/targetgroup"
31+
"github.com/prometheus/prometheus/model/labels"
3132
"github.com/prometheus/prometheus/model/relabel"
3233
"github.com/stretchr/testify/require"
3334
ctrl "sigs.k8s.io/controller-runtime"
@@ -48,13 +49,14 @@ func BenchmarkProcessTargets(b *testing.B) {
4849
targetsPerGroup := 5
4950
groupsPerJob := 20
5051
tsets := prepareBenchmarkData(numTargets, targetsPerGroup, groupsPerJob)
52+
labelsBuilder := labels.NewBuilder(labels.EmptyLabels())
5153

5254
b.ResetTimer()
5355
for _, strategy := range allocation.GetRegisteredAllocatorNames() {
5456
b.Run(strategy, func(b *testing.B) {
5557
targetDiscoverer, allocator := createTestDiscoverer(strategy, map[string][]*relabel.Config{})
5658
for i := 0; i < b.N; i++ {
57-
targetDiscoverer.ProcessTargets(tsets, allocator.SetTargets)
59+
targetDiscoverer.ProcessTargets(labelsBuilder, tsets, allocator.SetTargets)
5860
}
5961
})
6062
}
@@ -67,6 +69,7 @@ func BenchmarkProcessTargetsWithRelabelConfig(b *testing.B) {
6769
targetsPerGroup := 5
6870
groupsPerJob := 20
6971
tsets := prepareBenchmarkData(numTargets, targetsPerGroup, groupsPerJob)
72+
labelsBuilder := labels.NewBuilder(labels.EmptyLabels())
7073
prehookConfig := make(map[string][]*relabel.Config, len(tsets))
7174
for jobName := range tsets {
7275
// keep all targets in half the jobs, drop the rest
@@ -93,7 +96,7 @@ func BenchmarkProcessTargetsWithRelabelConfig(b *testing.B) {
9396
b.Run(strategy, func(b *testing.B) {
9497
targetDiscoverer, allocator := createTestDiscoverer(strategy, prehookConfig)
9598
for i := 0; i < b.N; i++ {
96-
targetDiscoverer.ProcessTargets(tsets, allocator.SetTargets)
99+
targetDiscoverer.ProcessTargets(labelsBuilder, tsets, allocator.SetTargets)
97100
}
98101
})
99102
}

cmd/otel-allocator/prehook/relabel.go

+3-19
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package prehook
1616

1717
import (
1818
"github.com/go-logr/logr"
19-
"github.com/prometheus/common/model"
20-
"github.com/prometheus/prometheus/model/labels"
2119
"github.com/prometheus/prometheus/model/relabel"
2220

2321
"github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/target"
@@ -35,18 +33,6 @@ func NewRelabelConfigTargetFilter(log logr.Logger) Hook {
3533
}
3634
}
3735

38-
// helper function converts from model.LabelSet to []labels.Label.
39-
func convertLabelToPromLabelSet(lbls model.LabelSet) []labels.Label {
40-
newLabels := make([]labels.Label, len(lbls))
41-
index := 0
42-
for k, v := range lbls {
43-
newLabels[index].Name = string(k)
44-
newLabels[index].Value = string(v)
45-
index++
46-
}
47-
return newLabels
48-
}
49-
5036
func (tf *RelabelConfigTargetFilter) Apply(targets map[string]*target.Item) map[string]*target.Item {
5137
numTargets := len(targets)
5238

@@ -58,13 +44,11 @@ func (tf *RelabelConfigTargetFilter) Apply(targets map[string]*target.Item) map[
5844
// Note: jobNameKey != tItem.JobName (jobNameKey is hashed)
5945
for jobNameKey, tItem := range targets {
6046
keepTarget := true
61-
lset := convertLabelToPromLabelSet(tItem.Labels)
47+
lset := tItem.Labels
6248
for _, cfg := range tf.relabelCfg[tItem.JobName] {
63-
if newLset, keep := relabel.Process(lset, cfg); !keep {
64-
keepTarget = false
49+
lset, keepTarget = relabel.Process(lset, cfg)
50+
if !keepTarget {
6551
break // inner loop
66-
} else {
67-
lset = newLset
6852
}
6953
}
7054

cmd/otel-allocator/prehook/relabel_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"testing"
2323

2424
"github.com/prometheus/common/model"
25+
"github.com/prometheus/prometheus/model/labels"
2526
"github.com/prometheus/prometheus/model/relabel"
2627
"github.com/stretchr/testify/assert"
2728
logf "sigs.k8s.io/controller-runtime/pkg/log"
@@ -184,10 +185,10 @@ func makeNNewTargets(rCfgs []relabelConfigObj, n int, numCollectors int, startin
184185
relabelConfig := make(map[string][]*relabel.Config)
185186
for i := startingIndex; i < n+startingIndex; i++ {
186187
collector := fmt.Sprintf("collector-%d", colIndex(i, numCollectors))
187-
label := model.LabelSet{
188-
"collector": model.LabelValue(collector),
189-
"i": model.LabelValue(strconv.Itoa(i)),
190-
"total": model.LabelValue(strconv.Itoa(n + startingIndex)),
188+
label := labels.Labels{
189+
{Name: "collector", Value: collector},
190+
{Name: "i", Value: strconv.Itoa(i)},
191+
{Name: "total", Value: strconv.Itoa(n + startingIndex)},
191192
}
192193
jobName := fmt.Sprintf("test-job-%d", i)
193194
newTarget := target.NewItem(jobName, "test-url", label, collector)

cmd/otel-allocator/server/bench_test.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/gin-gonic/gin"
2525
"github.com/prometheus/common/model"
2626
promconfig "github.com/prometheus/prometheus/config"
27+
"github.com/prometheus/prometheus/model/labels"
2728
"github.com/stretchr/testify/assert"
2829

2930
"github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/allocation"
@@ -249,12 +250,13 @@ func makeNCollectorJSON(random rand.Rand, numCollectors, numItems int) map[strin
249250
}
250251

251252
func makeNTargetItems(random rand.Rand, numItems, numLabels int) []*target.Item {
253+
builder := labels.NewBuilder(labels.EmptyLabels())
252254
items := make([]*target.Item, 0, numItems)
253255
for i := 0; i < numItems; i++ {
254256
items = append(items, target.NewItem(
255257
randSeq(random, 80),
256258
randSeq(random, 150),
257-
makeNNewLabels(random, numLabels),
259+
makeNNewLabels(builder, random, numLabels),
258260
randSeq(random, 30),
259261
))
260262
}
@@ -270,10 +272,10 @@ func makeNTargetJSON(random rand.Rand, numItems, numLabels int) []*targetJSON {
270272
return targets
271273
}
272274

273-
func makeNNewLabels(random rand.Rand, n int) model.LabelSet {
274-
labels := make(map[model.LabelName]model.LabelValue, n)
275+
func makeNNewLabels(builder *labels.Builder, random rand.Rand, n int) labels.Labels {
276+
builder.Reset(labels.EmptyLabels())
275277
for i := 0; i < n; i++ {
276-
labels[model.LabelName(randSeq(random, 20))] = model.LabelValue(randSeq(random, 20))
278+
builder.Set(randSeq(random, 20), randSeq(random, 20))
277279
}
278-
return labels
280+
return builder.Labels()
279281
}

cmd/otel-allocator/server/server.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import (
3434
"github.com/prometheus/client_golang/prometheus/promauto"
3535
"github.com/prometheus/client_golang/prometheus/promhttp"
3636
promcommconfig "github.com/prometheus/common/config"
37-
"github.com/prometheus/common/model"
3837
promconfig "github.com/prometheus/prometheus/config"
38+
"github.com/prometheus/prometheus/model/labels"
3939
"gopkg.in/yaml.v2"
4040

4141
"github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/allocation"
@@ -67,8 +67,8 @@ type linkJSON struct {
6767
}
6868

6969
type targetJSON struct {
70-
TargetURL []string `json:"targets"`
71-
Labels model.LabelSet `json:"labels"`
70+
TargetURL []string `json:"targets"`
71+
Labels labels.Labels `json:"labels"`
7272
}
7373

7474
type Server struct {
@@ -374,7 +374,7 @@ func registerPprof(g *gin.RouterGroup) {
374374

375375
func targetJsonFromTargetItem(item *target.Item) *targetJSON {
376376
return &targetJSON{
377-
TargetURL: item.TargetURL,
377+
TargetURL: []string{item.TargetURL},
378378
Labels: item.Labels,
379379
}
380380
}

cmd/otel-allocator/server/server_test.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/prometheus/common/config"
2929
"github.com/prometheus/common/model"
3030
promconfig "github.com/prometheus/prometheus/config"
31+
"github.com/prometheus/prometheus/model/labels"
3132
"github.com/prometheus/prometheus/model/relabel"
3233
"github.com/stretchr/testify/assert"
3334
"github.com/stretchr/testify/require"
@@ -41,11 +42,11 @@ import (
4142

4243
var (
4344
logger = logf.Log.WithName("server-unit-tests")
44-
baseLabelSet = model.LabelSet{
45-
"test_label": "test-value",
45+
baseLabelSet = labels.Labels{
46+
{Name: "test_label", Value: "test-value"},
4647
}
47-
testJobLabelSetTwo = model.LabelSet{
48-
"test_label": "test-value2",
48+
testJobLabelSetTwo = labels.Labels{
49+
{Name: "test_label", Value: "test-value2"},
4950
}
5051
baseTargetItem = target.NewItem("test-job", "test-url", baseLabelSet, "test-collector")
5152
secondTargetItem = target.NewItem("test-job", "test-url", baseLabelSet, "test-collector")
@@ -108,8 +109,8 @@ func TestServer_TargetsHandler(t *testing.T) {
108109
items: []*targetJSON{
109110
{
110111
TargetURL: []string{"test-url"},
111-
Labels: map[model.LabelName]model.LabelValue{
112-
"test_label": "test-value",
112+
Labels: labels.Labels{
113+
{Name: "test_label", Value: "test-value"},
113114
},
114115
},
115116
},
@@ -130,8 +131,8 @@ func TestServer_TargetsHandler(t *testing.T) {
130131
items: []*targetJSON{
131132
{
132133
TargetURL: []string{"test-url"},
133-
Labels: map[model.LabelName]model.LabelValue{
134-
"test_label": "test-value",
134+
Labels: labels.Labels{
135+
{Name: "test_label", Value: "test-value"},
135136
},
136137
},
137138
},
@@ -152,14 +153,14 @@ func TestServer_TargetsHandler(t *testing.T) {
152153
items: []*targetJSON{
153154
{
154155
TargetURL: []string{"test-url"},
155-
Labels: map[model.LabelName]model.LabelValue{
156-
"test_label": "test-value",
156+
Labels: labels.Labels{
157+
{Name: "test_label", Value: "test-value"},
157158
},
158159
},
159160
{
160161
TargetURL: []string{"test-url2"},
161-
Labels: map[model.LabelName]model.LabelValue{
162-
"test_label": "test-value2",
162+
Labels: labels.Labels{
163+
{Name: "test_label", Value: "test-value2"},
163164
},
164165
},
165166
},
@@ -572,7 +573,7 @@ func TestServer_JobHandler(t *testing.T) {
572573
{
573574
description: "one job",
574575
targetItems: map[string]*target.Item{
575-
"targetitem": target.NewItem("job1", "", model.LabelSet{}, ""),
576+
"targetitem": target.NewItem("job1", "", labels.Labels{}, ""),
576577
},
577578
expectedCode: http.StatusOK,
578579
expectedJobs: map[string]linkJSON{
@@ -582,11 +583,11 @@ func TestServer_JobHandler(t *testing.T) {
582583
{
583584
description: "multiple jobs",
584585
targetItems: map[string]*target.Item{
585-
"a": target.NewItem("job1", "", model.LabelSet{}, ""),
586-
"b": target.NewItem("job2", "", model.LabelSet{}, ""),
587-
"c": target.NewItem("job3", "", model.LabelSet{}, ""),
588-
"d": target.NewItem("job3", "", model.LabelSet{}, ""),
589-
"e": target.NewItem("job3", "", model.LabelSet{}, "")},
586+
"a": target.NewItem("job1", "", labels.Labels{}, ""),
587+
"b": target.NewItem("job2", "", labels.Labels{}, ""),
588+
"c": target.NewItem("job3", "", labels.Labels{}, ""),
589+
"d": target.NewItem("job3", "", labels.Labels{}, ""),
590+
"e": target.NewItem("job3", "", labels.Labels{}, "")},
590591
expectedCode: http.StatusOK,
591592
expectedJobs: map[string]linkJSON{
592593
"job1": newLink("job1"),

0 commit comments

Comments
 (0)