Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimise relabeling by re-using memory #11147

Merged
merged 7 commits into from
Aug 19, 2022
Merged

Conversation

bboreham
Copy link
Member

Relabeling can be a large portion of Prometheus memory allocation, and hence overall performance.
Especially relabeling in service discovery.

Since relabelling works by applying different rules to the same label set, we can re-use slices and greatly reduce memory allocation. Also re-use the Builder itself since NewBuilder() makes some speculative allocations.

The benchmark is somewhat lengthy, due to including realistic data.

name                  old time/op    new time/op    delta
Relabel/example-4       5.32µs ± 4%    4.10µs ± 2%  -22.92%  (p=0.008 n=5+5)
Relabel/kubernetes-4    50.0µs ± 7%    33.6µs ± 2%  -32.93%  (p=0.008 n=5+5)

name                  old alloc/op   new alloc/op   delta
Relabel/example-4       1.83kB ± 0%    0.74kB ± 0%  -59.66%  (p=0.000 n=4+5)
Relabel/kubernetes-4    26.3kB ± 0%     3.4kB ± 0%  -87.07%  (p=0.008 n=5+5)

name                  old allocs/op  new allocs/op  delta
Relabel/example-4         33.0 ± 0%      23.0 ± 0%  -30.30%  (p=0.008 n=5+5)
Relabel/kubernetes-4       106 ± 0%        44 ± 0%  -58.49%  (p=0.008 n=5+5)

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
Saves memory allocations.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This reduces memory allocations where the caller has a suitable slice available.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
To reduce memory allocations.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
Restore original behaviour in PopulateLabels, where we must not overwrite the input set.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
Use a stack-based array for up to 16 source labels, which will be the
vast majority of cases.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
@bboreham
Copy link
Member Author

I pushed another commit which re-does "re-use source values slice" in a simpler way, and reduces allocations by 1 more.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
@@ -192,24 +192,29 @@ func (re Regexp) String() string {
// are applied in order of input.
// If a label set is dropped, nil is returned.
// May return the input labelSet modified.
func Process(labels labels.Labels, cfgs ...*Config) labels.Labels {
func Process(lbls labels.Labels, cfgs ...*Config) labels.Labels {
lb := labels.NewBuilder(nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like another interface called ProcessWithBuilder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK; is that relevant to this PR?
If not, it would belong in a separate PR with its own justification.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about using a pool of Builders here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could also be done inside Process without changing the api.

Copy link
Member

@codesome codesome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a comment

Comment on lines +207 to +211
var va [16]string
values := va[:0]
if len(cfg.SourceLabels) > cap(values) {
values = make([]string, 0, len(cfg.SourceLabels))
}
Copy link
Member

@codesome codesome Aug 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this better than the previous?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, would re-using the values slice between the relabel calls make it better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For relabeling rules with up to 16 source labels (surely most real-life examples), it uses an array on the stack, thus performs no heap allocation.

I tried re-using the slice; see 135e517. It is more complicated and does one allocation in every case, compared to zero in most cases.

@codesome codesome merged commit 8b863c4 into prometheus:main Aug 19, 2022
Mama59 pushed a commit to Arnoways/prometheus that referenced this pull request Aug 25, 2022
* model/relabel: Add benchmark

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* model/relabel: re-use Builder across relabels

Saves memory allocations.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* labels.Builder: allow re-use of result slice

This reduces memory allocations where the caller has a suitable slice available.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* model/relabel: re-use source values slice

To reduce memory allocations.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* Unwind one change causing test failures

Restore original behaviour in PopulateLabels, where we must not overwrite the input set.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* relabel: simplify values optimisation

Use a stack-based array for up to 16 source labels, which will be the
vast majority of cases.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

* lint

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
valyala added a commit to VictoriaMetrics/VictoriaMetrics that referenced this pull request Oct 1, 2022
valyala added a commit to VictoriaMetrics/VictoriaMetrics that referenced this pull request Oct 1, 2022
@codesome codesome mentioned this pull request Oct 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants