-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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: Trend as Histogram #3027
Conversation
fdc5307
to
bfff8af
Compare
78c9580
to
1a45956
Compare
Codecov Report
@@ Coverage Diff @@
## master #3027 +/- ##
==========================================
+ Coverage 73.57% 73.68% +0.10%
==========================================
Files 240 241 +1
Lines 18364 18436 +72
==========================================
+ Hits 13512 13585 +73
+ Misses 3980 3978 -2
- Partials 872 873 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
8396f62
to
d7df637
Compare
63df8df
to
fb719c9
Compare
d7df637
to
34d36f7
Compare
34d36f7
to
580f02b
Compare
580f02b
to
4c09c5e
Compare
fb719c9
to
40ad58a
Compare
4c09c5e
to
2fb9e2d
Compare
40ad58a
to
6e4d987
Compare
// let n = msb(u) - most significant digit position | ||
// i.e. n = floor(log(u, 2)) | ||
// major_bucket_index = n - k + 1 | ||
// sub_bucket_index = u>>(n - k) - (1<<k) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this mostly as a reminder to myself to double-check next week, since I don't immediately understand this line - why can sub_bucket_index
be calculated like this? 🤔
The n
th bucket contains [2^(n-1) : 2^n]
values, equally divided in 2^k
sub-buckets, right? So, I'd expect something like "zero out up to the n
th bit to get the part of the number that needs to be divided into sub-buckets, divide it by 2^k
to get the sub-bucket index".
But I'm probably missing something stupid, so if you have an explanation handy, please add it to the comment
b3821f5
to
46f3fdf
Compare
e2152b8
to
1d7eed8
Compare
ede28b0
to
d2add9c
Compare
const ( | ||
// lowestTrackable represents the minimum value that the histogram tracks. | ||
// Essentially, it excludes negative numbers. | ||
// Most of metrics tracked by histograms are durations | ||
// where we don't expect negative numbers. | ||
// | ||
// In the future, we may expand and include them, | ||
// probably after https://github.com/grafana/k6/issues/763. | ||
lowestTrackable = 0 | ||
|
||
// highestTrackable represents the maximum | ||
// value that the histogram is able to track with high accuracy (0.1% of error). | ||
// It should be a high enough | ||
// and rationale value for the k6 context; 2^30 = 1_073_741_824 | ||
highestTrackable = 1 << 30 | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This IMO should be very well communicated and documented somewhere as I am not certain these were restrictions so far.
I doubt that many users use that big values or negative ones.
Is there a reason why we are removing negative values to begin with? As in this algorithm just does not work with them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also link the algorithm used in:
- the code
- the commit
- the PR
- (likely) the docs when they are added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why we are removing negative values to begin with? As in this algorithm just does not work with them?
My understanding of the original design is we did it with the assumption that most of the time we measure duration, and they are not negative. So it simplified the requirement for the algorithm.
output/cloud/expv2/hdr.go
Outdated
if index < h.FirstNotZeroBucket { | ||
h.growLeft(index) | ||
h.FirstNotZeroBucket = index | ||
} | ||
if index > h.LastNotZeroBucket { | ||
h.growRight(index) | ||
h.LastNotZeroBucket = index | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very likely for a future optimization:
For every given timeseries this bucket will likely just be recreated each bucket. This can potentially mean many allocations of slices over and over again across all time series for the whole duration of the test.
There are quite a few possibilities to mitigate this:
- obviously do nothing and see how it goes :)
- reuse the same
histogram
and all of its' buckets. This likely will be easier ifhistogramAsProto
is called when the metrics are flushed and the whole instance is just set for the next bucket after it ... this seems very iffy to me. - On each creation of a new histogram we can check if the previous bucket has a histogram for the same timeseries - copy its buckets (without the values obviously). This likely will be easier and we only pay the costs when a new histogram is added.
- something else that I forgot while typing :(
- Something else we come up with
I will expect this is a common problem so maybe someone has already solved it in the golang space.
The hdrhistogram-go repo has Snapshot
(and a much bigger Histogram) which seems like a way to get values (snapshot) for some time and then continue to aggregate without needing to create the buckets
from scratch.
Although in their case it is just a continues aggregation while we want to reset.
Not allocate anymore buckets before and after the first and the last non-zero bucket. It saves a bunch of memory.
d2add9c
to
128e55a
Compare
Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
4846b3c
to
f63d2e6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I have left a naming nitpick which we can address later or never for that matter 😅
Custom Histogram representation of the Trend metric type. It is the porting of the Histogram generation on the client side.