-
Notifications
You must be signed in to change notification settings - Fork 634
MQE: add support for topk
and bottomk
#10614
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
858b84a
to
a6aa656
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.
We should put this through the gauntlet, at least for instant queries to confirm the order.
We should also have a feature flag for this operator since it doesn't reuse most of the aggregation operator.
(I need to review range_query a bit closer still, but at first glance looks good)
pkg/streamingpromql/operators/aggregations/topkbottomk/topk_bottomk.go
Outdated
Show resolved
Hide resolved
// whereas this method does. | ||
// This saves us allocating a new buffer and string for every single input series, which has a noticeable performance impact. | ||
type seriesToGroupLabelsBytesFunc func(labels.Labels) []byte | ||
func (a *Aggregation) groupLabelsBytesFunc() SeriesToGroupLabelsBytesFunc { |
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 don't think this needs to be a method any more. We should be able to just use GroupLabelsBytesFunc
on line 138 (same with the new operators too)
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've changed this in the new operators, but TestAggregation_GroupLabelling
uses this method, so I'd prefer to keep it as-is in Aggregation
.
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.
(not blocking) Why not update those tests?
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.
To me, it's more valuable to test the Aggregation
operator itself, as it does some work to make these tests pass (eg. adding the __name__
label to the list of labels when without
is used) - the fact it uses a shared function is more of an implementation detail.
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query.go
Outdated
Show resolved
Hide resolved
pkg/streamingpromql/operators/aggregations/topkbottomk/instant_query.go
Outdated
Show resolved
Hide resolved
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query.go
Outdated
Show resolved
Hide resolved
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query_test.go
Show resolved
Hide resolved
I did try this, but it would not be straightforward:
|
Isn't this covered by |
62f545c
to
f49c2b8
Compare
Sorry I missed that. I wonder if we can create a similar gauntlet for these aggregations that only has deterministic combinations? It'd still be good to test more combinations such as stale markers and infinities etc. |
Heh, yep, that works. |
pkg/streamingpromql/operators/aggregations/topkbottomk/instant_query.go
Outdated
Show resolved
Hide resolved
We already have some tests that cover the behaviour of |
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.
Looking good, thanks! Just a last few things
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query.go
Outdated
Show resolved
Hide resolved
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query.go
Outdated
Show resolved
Hide resolved
pkg/streamingpromql/operators/aggregations/topkbottomk/range_query.go
Outdated
Show resolved
Hide resolved
return nil | ||
} | ||
|
||
if len(g.seriesForTimestamps[timestampIndex]) == int(limit) { |
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.
(nit) point selection/interacting with the heap could be split out into own method
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've moved the other methods out in 54bba6e, which should help make this a little shorter - how's this now?
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 still feel this if/else block could be extracted so we have accumulateIntoGroup
dealing with getting the series for the group, and a new method such as updateHeapForGroup
or similar for dealing with the heap selection etc. (again, jsut a nit)
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.
Done in #10679
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, thanks for dealing with my feedback :-)
I'm going to merge this as-is so we can start testing it next week, but I will come back and address some of the refactoring as a follow-up PR. |
* Enable upstream test cases * Enable benchmark * Add our own test cases * Initial implementation * Fix issue where queries that use `count_values` fail rather than reporting that they are unsupported * Add benchmark with grouping * Add tests for grouping and sorting * Reuse same heap instance to avoid allocating on every input sample. * Add shortcut for case where k=1 * Pool slices of `topKBottomKSeries` * Pool `[][]int` slices * Move to separate package * Initial implementation of sorting for instant queries * Fix sorting of NaN values for instant queries * Expand test cases to cover instant queries as well * Add license headers * Address PR feedback: don't bother allocating a new slice when used with `without` * Address PR feedback related to `GroupLabelsBytesFunc` * Address PR feedback: refactor `GroupLabelsBytesFunc` * Address PR feedback: add and clarify comments * Address PR feedback: rename `limit` to `k` * Rename `topKBottomKSeries` to `rangeQuerySeries` * Add pooling for `[]instantQuerySeries` * Address PR feedback: add further test cases with NaN and infinite values * Add test for instant query sorting and grouping * Address PR feedback: clarify comments * Address PR feedback: clarify error message * Address PR feedback: extract functions
* Enable upstream test cases * Enable benchmark * Add our own test cases * Initial implementation * Fix issue where queries that use `count_values` fail rather than reporting that they are unsupported * Add benchmark with grouping * Add tests for grouping and sorting * Reuse same heap instance to avoid allocating on every input sample. * Add shortcut for case where k=1 * Pool slices of `topKBottomKSeries` * Pool `[][]int` slices * Move to separate package * Initial implementation of sorting for instant queries * Fix sorting of NaN values for instant queries * Expand test cases to cover instant queries as well * Add license headers * Address PR feedback: don't bother allocating a new slice when used with `without` * Address PR feedback related to `GroupLabelsBytesFunc` * Address PR feedback: refactor `GroupLabelsBytesFunc` * Address PR feedback: add and clarify comments * Address PR feedback: rename `limit` to `k` * Rename `topKBottomKSeries` to `rangeQuerySeries` * Add pooling for `[]instantQuerySeries` * Address PR feedback: add further test cases with NaN and infinite values * Add test for instant query sorting and grouping * Address PR feedback: clarify comments * Address PR feedback: clarify error message * Address PR feedback: extract functions
What this PR does
This PR adds support for
topk
andbottomk
to MQE.Note that I have not added
topk
andbottomk
to the mixed metrics gauntlet as there are many false-positive failures:topk
andbottomk
do not guarantee which series will be returned when multiple series in a group have the same value, and due to differences in Prometheus' engine and MQE, they each select different series in these cases.Compared to Prometheus' engine, MQE is up to 30% faster and uses up to 70% less memory at peak for non-trivial benchmarks:
Which issue(s) this PR fixes or relates to
#10067
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]
.about-versioning.md
updated with experimental features.