-
Notifications
You must be signed in to change notification settings - Fork 817
Don't convert chunks to matrixes and then merges them... #713
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
Conversation
723cfc7
to
71707d3
Compare
Having deployed this to our dev env I didn't see the kind of speed up I was expecting. On investigation the code is very sensitive to "chunk density" - how many chunks there are per 48 hours. I originally modelling it at 48 (one per hour, each 3 hours long), but modelling as one every 6 mins more closely matches the performance I see in dev. The good news is its still an improvement, but just not as much as before:
|
We're seeing some more issues with this in testing. Worth reviewing, but don't merge yet. |
c00829b
to
1b4861c
Compare
I've resurrected this and fixed the correctness issues (by expanding the tests). Current performance:
Old path (matrixes) is faster, but 60x more memory usage. Going to see if I can improve this a bit. |
3bcb1d9
to
008a714
Compare
Found an optimisation in the ChunksToMatrix function too, so results are now:
I suspect it might make sense to pick the strategy (iterate or merge) based on the length of the query (or the number of chunks in the series). |
Needed to update the vendored Prometheus for prometheus/prometheus@78efdc6d |
- Refactor chunk store to return chunks. - Refactor querier package to use new Prometheus 2.0 interfaces. - Have separate querier for ingesters, chunk store and metadata. - Make remote read handler take a Queryable. Signed-off-by: Tom Wilkie <[email protected]>
… PromQL query. Signed-off-by: Tom Wilkie <[email protected]>
…and the upstream heap-based merging code. Signed-off-by: Tom Wilkie <[email protected]>
Signed-off-by: Tom Wilkie <[email protected]>
…ate NaN values Signed-off-by: Tom Wilkie <[email protected]>
Signed-off-by: Tom Wilkie <[email protected]>
pkg/chunk/chunk.go
Outdated
} | ||
sp.LogFields(otlog.Int("sample streams", len(sampleStreams))) | ||
sp.LogFields(otlog.Int("sample streams", len(samples))) |
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.
The log name should probably be samples as well
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.
Variable name is misleading I think - its a map from fingerprint to list of list of samples (so we can do a proper tree-based merge later). Have updated variable name to samplesBySeries
and change log key to series
.
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.
One small comment, otherwise LGTM.
Are you thinking at some point use matrix for queries with a small number of chunks for speed, and iterator for a large number of chunks to not OOM?
Signed-off-by: Tom Wilkie <[email protected]>
Right now I'm just trying to stop the querier OOMing for high cardinality / long queries / lots of simultaneous queries. But yeah, once I've got that working it probably makes a lot of sense to switch based on number of chunks per series - good idea! |
...use iterators instead.
Also:
Big drawback of this approach is the optimisation necessary about
Seek
- as we don't know the end time for any particular-seek'd iterator, we aren't technically able to filter out chunks in the future. This has a large performance impact (basically O(n^2)), as seeks at the very beginning of the range have to include all chunks. To avoid this I've assumed an end time of 48hrs, meaning vector queries with duration larger than 24hrs won't work correctly (iesum(rate(foo[48h]))
). But OTOH this allows code closer to O(n log n).Before vs after:
Thats about 8.2x speed up in ns/op and 62x less memory usage.
Part of #209, closes #81 as redundant.