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

output/cloudv2: Compact histogram #3169

Merged
merged 8 commits into from
Jul 10, 2023
Merged

Conversation

codebien
Copy link
Contributor

@codebien codebien commented Jul 5, 2023

What?

Implementation of a more compact Protobuf representation for the Histogram type. This new version only stores and pushes the histogram's significant buckets (non-zero).

Why?

The current implementation only trims the zero at the limit of the histogram, doing a massive waste of memory if the histogram has a sparse representation. The new version instead allocates only for non-zero buckets.

Related PR(s)/Issue(s)

Updates #3117

@codebien codebien added the cloud label Jul 5, 2023
@codebien codebien added this to the v0.46.0 milestone Jul 5, 2023
@codebien codebien self-assigned this Jul 5, 2023
@codebien codebien mentioned this pull request Jul 5, 2023
@codecov-commenter
Copy link

codecov-commenter commented Jul 6, 2023

Codecov Report

Merging #3169 (2a23ec4) into master (0fb962b) will decrease coverage by 0.20%.
The diff coverage is 70.96%.

❗ Current head 2a23ec4 differs from pull request most recent head 1ec8c97. Consider uploading reports for the commit 1ec8c97 to get more accurate results

@@            Coverage Diff             @@
##           master    #3169      +/-   ##
==========================================
- Coverage   72.83%   72.63%   -0.20%     
==========================================
  Files         255      253       -2     
  Lines       19611    19630      +19     
==========================================
- Hits        14283    14259      -24     
- Misses       4432     4469      +37     
- Partials      896      902       +6     
Flag Coverage Δ
ubuntu 72.63% <70.96%> (-0.14%) ⬇️
windows ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
output/cloud/expv2/pbcloud/metric.pb.go 27.23% <27.02%> (-0.26%) ⬇️
output/cloud/expv2/hdr.go 100.00% <100.00%> (+2.85%) ⬆️
output/cloud/expv2/output.go 66.45% <100.00%> (ø)
output/cloud/expv2/sink.go 92.30% <100.00%> (ø)

... and 11 files with indirect coverage changes

The histogram now uses a more compact solution for storing the
distribution. It tracks only the significant buckets.
@codebien codebien marked this pull request as ready for review July 6, 2023 14:22
@github-actions github-actions bot requested review from mstoykov and oleiade July 6, 2023 14:22
@codebien codebien requested review from olegbespalov and removed request for oleiade July 6, 2023 14:22
Comment on lines 41 to 47
// It does not include counters for the untrackable values,
// because they contain exception cases and require to be tracked in a dedicated way.
Buckets map[uint32]uint32

// Indexes keeps an ordered slice of unique-seen buckets' indexes.
// It allows to iterate the buckets in order. It uses an ascendent order.
Indexes []uint32
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We may consider using a Btree as an optimization. But I would like to achieve stability in the protocol before.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we can't just order the buckets indexes at the end 🤷. There is no need to constantly keep track of it -if we only want it to be in order 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it simplifies the code a lot, good suggestion.

output/cloud/expv2/hdr.go Outdated Show resolved Hide resolved
spans []*pbcloud.BucketSpan
)

// allocate only if at least one item is available
Copy link
Contributor

Choose a reason for hiding this comment

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

A dummy question, is it possible to have a histogram without values (and indexes)?

Copy link
Contributor

Choose a reason for hiding this comment

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

As we only send observed metrics in the aggregation time period - it should not be possible. The first time we see a metric we create the histogram structure and add the first sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without values not, but it is possible to have Indexes and Buckets empty when there are only untrackable values that are tracked into the special extreme buckets.

Comment on lines 102 to 103
if h.Buckets == nil {
h.Buckets = make(map[uint32]uint32)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be done just when we make the histogram struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I move it to a constructor

}
// if the current and the previous indexes are not consecutive
// consider as closed the current on-going span and start a new one.
if diff := h.Indexes[i] - h.Indexes[i-1]; diff > 1 {
Copy link
Contributor

@mstoykov mstoykov Jul 7, 2023

Choose a reason for hiding this comment

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

For more optimal space use this likely should be 3+ as adding 1 span is at least 2 counters (offset and length) .

So we can add at least 2 zeros before we became even. "at least" here is as I don't know if there is some more overhead for this in the protobuf protocol

edit: This can be done after the original merge as an optimization

mstoykov
mstoykov previously approved these changes Jul 7, 2023
Copy link
Contributor

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

LGTM! But we can probably fix some of the small fixes before merging.

The optimizations can likely wait a while and maybe benchmarks ;)

olegbespalov
olegbespalov previously approved these changes Jul 7, 2023
output/cloud/expv2/sink_test.go Outdated Show resolved Hide resolved
olegbespalov
olegbespalov previously approved these changes Jul 7, 2023
Copy link
Contributor

@olegbespalov olegbespalov left a comment

Choose a reason for hiding this comment

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

Great job! 🚀

mstoykov
mstoykov previously approved these changes Jul 7, 2023
@codebien codebien dismissed stale reviews from mstoykov and olegbespalov via 4f49f36 July 7, 2023 14:17
@codebien codebien requested a review from mstoykov July 7, 2023 14:51
@codebien codebien merged commit 3906dcf into master Jul 10, 2023
@codebien codebien deleted the cloduv2-compact-histogram branch July 10, 2023 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants