scrape: re-use memory in TargetsFromGroup

Common service discovery mechanisms such as Kubernetes can generate a
lot of target groups, so this function was allocating a lot of memory
which then immediately became garbage. Re-using the structures across
an entire Sync saves effort.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2023-03-07 09:23:34 +00:00
parent 5cfe759348
commit f4fd9b0d68
4 changed files with 14 additions and 7 deletions

View File

@ -1250,8 +1250,11 @@ func checkTargetGroupsForAlertmanager(targetGroups []*targetgroup.Group, amcfg *
}
func checkTargetGroupsForScrapeConfig(targetGroups []*targetgroup.Group, scfg *config.ScrapeConfig) error {
var targets []*scrape.Target
lb := labels.NewBuilder(labels.EmptyLabels())
for _, tg := range targetGroups {
_, failures := scrape.TargetsFromGroup(tg, scfg, false)
var failures []error
targets, failures = scrape.TargetsFromGroup(tg, scfg, false, targets, lb)
if len(failures) > 0 {
first := failures[0]
return first

View File

@ -490,9 +490,11 @@ func (sp *scrapePool) Sync(tgs []*targetgroup.Group) {
sp.targetMtx.Lock()
var all []*Target
var targets []*Target
lb := labels.NewBuilder(labels.EmptyLabels())
sp.droppedTargets = []*Target{}
for _, tg := range tgs {
targets, failures := TargetsFromGroup(tg, sp.config, sp.noDefaultPort)
targets, failures := TargetsFromGroup(tg, sp.config, sp.noDefaultPort, targets, lb)
for _, err := range failures {
level.Error(sp.logger).Log("msg", "Creating target failed", "err", err)
}

View File

@ -482,11 +482,10 @@ func PopulateLabels(lb *labels.Builder, cfg *config.ScrapeConfig, noDefaultPort
}
// TargetsFromGroup builds targets based on the given TargetGroup and config.
func TargetsFromGroup(tg *targetgroup.Group, cfg *config.ScrapeConfig, noDefaultPort bool) ([]*Target, []error) {
targets := make([]*Target, 0, len(tg.Targets))
func TargetsFromGroup(tg *targetgroup.Group, cfg *config.ScrapeConfig, noDefaultPort bool, targets []*Target, lb *labels.Builder) ([]*Target, []error) {
targets = targets[:0]
failures := []error{}
lb := labels.NewBuilder(labels.EmptyLabels())
for i, tlset := range tg.Targets {
lb.Reset(labels.EmptyLabels())

View File

@ -375,7 +375,8 @@ func TestTargetsFromGroup(t *testing.T) {
ScrapeTimeout: model.Duration(10 * time.Second),
ScrapeInterval: model.Duration(1 * time.Minute),
}
targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &cfg, false)
lb := labels.NewBuilder(labels.EmptyLabels())
targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &cfg, false, nil, lb)
if len(targets) != 1 {
t.Fatalf("Expected 1 target, got %v", len(targets))
}
@ -464,9 +465,11 @@ scrape_configs:
}
targets = append(targets, labels)
}
var tgets []*Target
lb := labels.NewBuilder(labels.EmptyLabels())
group := &targetgroup.Group{Targets: targets}
for i := 0; i < b.N; i++ {
targets, _ := TargetsFromGroup(group, config.ScrapeConfigs[0], false)
tgets, _ = TargetsFromGroup(group, config.ScrapeConfigs[0], false, tgets, lb)
if len(targets) != nTargets {
b.Fatalf("Expected %d targets, got %d", nTargets, len(targets))
}