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

fix(metrics): Track memory footprint more accurately [INGEST-1132] #1288

Merged
merged 10 commits into from
Jun 7, 2022

Conversation

jjbayer
Copy link
Member

@jjbayer jjbayer commented Jun 3, 2022

#1284 introduced a cost model for measuring the memory footprint of metrics buckets stored in the aggregator. It has two flaws:

  1. It did not take into account the fixed size overhead of a BucketValue (only looked at the values inside).
  2. It did not take into account the size overhead of storing the BucketKey.

This PR attempts to fix both issues.

relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
// Choosing a BTreeMap instead of a HashMap here, under the assumption that a BTreeMap
// is still more efficient for the number of project keys we store.
cost_per_project_key: BTreeMap<ProjectKey, usize>,
cost_per_project_key: HashMap<ProjectKey, usize>,
Copy link
Member Author

Choose a reason for hiding this comment

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

I did not run any benchmarks, but figured that a HashMap is a safer choice w.r.t. scaling.

Copy link
Member

Choose a reason for hiding this comment

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

it's fine either way. btreemap might have an edge for small values

relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
relay-metrics/src/aggregation.rs Outdated Show resolved Hide resolved
@@ -1287,7 +1339,7 @@ impl Aggregator {

let flush_at = self.config.get_flush_time(timestamp, project_key);
let bucket = value.into();
added_cost = bucket.cost();
added_cost = entry.key().cost() + bucket.cost();
Copy link
Member

Choose a reason for hiding this comment

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

While at it, it would be good to deal with the Occupied branch too. See #1287 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

The Occupied branch is handled correctly (though not elegantly):

let cost_before = bucket_value.cost();
value.merge_into(bucket_value)?;
let cost_after = bucket_value.cost();
added_cost = cost_after.saturating_sub(cost_before);

The advantage of computing the cost twice and subtracting is that we only need a single function for computing bucket value cost. If we did something like added_cost = if something_added { value.incremental_cost() } else { 0 }, we would need to also implement an incremental_cost function on BucketValue and MetricValue.

@jjbayer jjbayer marked this pull request as ready for review June 7, 2022 07:37
@jjbayer jjbayer requested a review from a team June 7, 2022 07:37
// Choosing a BTreeMap instead of a HashMap here, under the assumption that a BTreeMap
// is still more efficient for the number of project keys we store.
cost_per_project_key: BTreeMap<ProjectKey, usize>,
cost_per_project_key: HashMap<ProjectKey, usize>,
Copy link
Member

Choose a reason for hiding this comment

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

it's fine either way. btreemap might have an edge for small values

let value = std::mem::replace(&mut entry.value, BucketValue::Counter(0.0));
cost_tracker.subtract_cost(key.project_key, value.cost());
let value = mem::replace(&mut entry.value, BucketValue::Counter(0.0));
cost_tracker.subtract_cost(key.project_key, key.cost() + value.cost());
Copy link
Member

Choose a reason for hiding this comment

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

can we call subtract_cost twice instead? then overflow/underflow handling is also dealt with in one place

@jjbayer jjbayer merged commit 192a8eb into master Jun 7, 2022
@jjbayer jjbayer deleted the ref/track-metrics-footprint-2 branch June 7, 2022 14:41
jan-auer added a commit that referenced this pull request Jun 9, 2022
* master:
  ref(metrics): Stop logging relative bucket size (#1302)
  fix(metrics): Rename misnamed aggregator option (#1298)
  fix(server): Avoid a panic in the Sentry middleware (#1301)
  build: Update dependencies with known vulnerabilities (#1294)
  fix(metrics): Stop logging statsd metric per project key (#1295)
  feat(metrics): Limits on bucketing cost in aggregator [INGEST-1132] (#1287)
  fix(metrics): Track memory footprint more accurately (#1288)
  build(deps): Bump dependencies (#1293)
  feat(aws): Add relay-aws-extension crate which implements AWS extension as an actor (#1277)
  fix(meta): Update codeowners for the release actions (#1286)
  feat(metrics): Track memory footprint of metrics buckets (#1284)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants