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

No memory leakage in attributes filter #3695

Merged
merged 5 commits into from Feb 13, 2023

Conversation

regeda
Copy link
Contributor

@regeda regeda commented Feb 8, 2023

The attributes filter collects seen attributes in order to avoid filtration on the same attribute set. However, the attribute.Set is not comparable type and new allocations of sets with same attributes will be considered as new sets.

Metrics with a high cardinality of attributes consume a lot of memory even if we set a filter to reduce that cardinality.

The attributes filter collects seen attributes in order to avoid
filtration on the same attribute set. However, the `attribute.Set` is
not comparable type and new allocations of sets with same attributes will be
considered as new sets.

Metrics with a high cardinality of attributes consume a lot of memory
even if we set a filter to reduce that cardinality.
@MrAlias
Copy link
Contributor

MrAlias commented Feb 8, 2023

However, the attribute.Set is not comparable type

Hmm, that's new. I guess if you have more than 10 attributes or those attributes have the new slice values they will compare the pointer values not the underlying values. This is a bug for other parts of the SDK as well.

Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

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

This seems reasonable to me.

If I recall correctly this map was added to act as a cache and reduce computation. If removing it helps reduce ever-expanding memory overhead at the cost of having to calculate the filter each time that seems reasonable to me.

@MadVikingGod thoughts?

@codecov
Copy link

codecov bot commented Feb 9, 2023

Codecov Report

Merging #3695 (ca5e08f) into main (f5a1497) will decrease coverage by 0.1%.
The diff coverage is 100.0%.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #3695     +/-   ##
=======================================
- Coverage   79.7%   79.6%   -0.1%     
=======================================
  Files        171     171             
  Lines      12673   12657     -16     
=======================================
- Hits       10103   10085     -18     
- Misses      2357    2359      +2     
  Partials     213     213             
Impacted Files Coverage Δ
sdk/metric/internal/filter.go 100.0% <100.0%> (ø)
sdk/trace/batch_span_processor.go 80.2% <0.0%> (-1.8%) ⬇️
exporters/jaeger/jaeger.go 91.1% <0.0%> (+0.8%) ⬆️

@MrAlias MrAlias added bug Something isn't working Skip Changelog PRs that do not require a CHANGELOG.md entry labels Feb 9, 2023
@MrAlias MrAlias added this to the Metric v0.37.0 milestone Feb 13, 2023
@MrAlias MrAlias merged commit 441a173 into open-telemetry:main Feb 13, 2023
@regeda regeda deleted the no-memory-leak-in-attr-filter branch February 14, 2023 09:32
@regeda regeda restored the no-memory-leak-in-attr-filter branch February 14, 2023 09:46
@regeda regeda deleted the no-memory-leak-in-attr-filter branch February 15, 2023 08:58
@jmacd
Copy link
Contributor

jmacd commented Feb 17, 2023

Aside:

However, the attribute.Set is not comparable type and new allocations of sets with same attributes will be considered as new sets.

I do not believe this is true. The attribute.Set mechanism constructs a comparable array of KeyValue. For slice-valued Values, this process is carried out recursively -- slices are represented as arrays so they can be comparable.

The attribute.Set logic is tested correct above 10 attributes, it just falls back to use of reflect for >10 attributes in a set. The cost of attribute set construction is the cost of constructing a specific-size array of KeyValue.

If there's a bug in this logic, we should fix it -- or was the underlying issue really about accumulation of distinct sets? I take it from the fix in this PR that the underlying issue was true cardinality, not a failure of the attribute.Set logic. I'll be glad to help if there's a problem!

@MrAlias
Copy link
Contributor

MrAlias commented Feb 17, 2023

Aside:

However, the attribute.Set is not comparable type and new allocations of sets with same attributes will be considered as new sets.

I do not believe this is true. The attribute.Set mechanism constructs a comparable array of KeyValue. For slice-valued Values, this process is carried out recursively -- slices are represented as arrays so they can be comparable.

The attribute.Set logic is tested correct above 10 attributes, it just falls back to use of reflect for >10 attributes in a set. The cost of attribute set construction is the cost of constructing a specific-size array of KeyValue.

If there's a bug in this logic, we should fix it -- or was the underlying issue really about accumulation of distinct sets? I take it from the fix in this PR that the underlying issue was true cardinality, not a failure of the attribute.Set logic. I'll be glad to help if there's a problem!

Indeed #3702

We double checked this and the latest version of attribute.Set is comparable.

liufuyang added a commit to einride/cloudrunner-go that referenced this pull request Feb 21, 2023
while waiting for the new 0.37 release, we update
otel/sdk/metric package to its current master head
to bring in a fix of the memory issue.

open-telemetry/opentelemetry-go#3695

later when 0.37 is out we can update all related packages
to that version
liufuyang added a commit to einride/cloudrunner-go that referenced this pull request Feb 21, 2023
while waiting for the new 0.37 release, we update
otel/sdk/metric package to its current master head
to bring in a fix of the memory issue.

open-telemetry/opentelemetry-go#3695

later when 0.37 is out we can update all related packages
to that version
ericwenn pushed a commit to einride/cloudrunner-go that referenced this pull request Feb 21, 2023
while waiting for the new 0.37 release, we update
otel/sdk/metric package to its current master head
to bring in a fix of the memory issue.

open-telemetry/opentelemetry-go#3695

later when 0.37 is out we can update all related packages
to that version
ericwenn pushed a commit to einride/cloudrunner-go that referenced this pull request Feb 22, 2023
while waiting for the new 0.37 release, we update
otel/sdk/metric package to its current master head
to bring in a fix of the memory issue.

open-telemetry/opentelemetry-go#3695

later when 0.37 is out we can update all related packages
to that version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Skip Changelog PRs that do not require a CHANGELOG.md entry
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

4 participants