Add Aggregation Execution Context#85011
Conversation
Adds a place to store information during aggregation execution and use this context to store the current tsid. It allows us to achieve 3x improvement in the timeseries aggregation execution speed. In a follow up PR, I would like to remove the inheritance of BucketCollector from Collector and instead try wrapping it into a collector when needed. This should prevent us form using getLeafCollector(LeafReaderContext ctx) method in a wrong context in future. Relates to elastic#74660
|
@elasticmachine run elasticsearch-ci/part-2 |
|
Pinging @elastic/es-analytics-geo (Team:Analytics) |
nik9000
left a comment
There was a problem hiding this comment.
What should we do about delayed stuff here? Right now I think it'd just get the last tsid, right?
|
|
||
| @Override | ||
| public LeafBucketCollector getLeafCollector(LeafReaderContext ctx) throws IOException { | ||
| public LeafBucketCollector getLeafCollector(LeafReaderContext ctx, AggregationExecutionContext aggCtx) throws IOException { |
There was a problem hiding this comment.
Should we stick the LeafReaderContext onto it?
| */ | ||
| protected abstract LeafBucketCollector getLeafCollector(LeafReaderContext ctx, LeafBucketCollector sub) throws IOException; | ||
|
|
||
| // TODO: Remove the |
Delayed stuff is not supported by time series, I think I added checked in the previous iterations. But it needs to be cleaned up a bit so it is more obvious. I will try to address this in the follow up refactoring I mentioned in the issue description. |
I wonder if you had a |
But, yeah, it can wait. |
| } else { | ||
| collectBucket(sub, doc, bucketOrdinal); | ||
| } | ||
| long bucketOrdinal = bucketOrds.add(bucket, aggCtx.getTsid()); |
There was a problem hiding this comment.
Should it add an assert to check aggCtx is not null, or check aggCtx null?
There was a problem hiding this comment.
We have a check much earlier that this aggregator runs in the correct environment to prevent NPE here. I don't really see the difference between failing it with NPE vs assert.
| private CheckedSupplier<BytesRef, IOException> tsidProvider; | ||
|
|
||
| public BytesRef getTsid() throws IOException { | ||
| return tsidProvider.get(); |
There was a problem hiding this comment.
Should it add a null check to tsidProvider to avoid NPE?
romseygeek
left a comment
There was a problem hiding this comment.
I think we can avoid the setter if you reorder things in search a little?
| */ | ||
| public class AggregationExecutionContext { | ||
|
|
||
| private CheckedSupplier<BytesRef, IOException> tsidProvider; |
There was a problem hiding this comment.
Can we make this final?
@romseygeek LeafBucketCollector needs the current id part of the LeafWalker and LeafWalker needs a reference to LeafBucketCollector. So, we have to ether make collector in LeafWalkerCollector non final, or move the entire initialization into LeafWalker constructor, but then we need to deal with null scorer by throwing an exception. What did you have in mind? What am I missing? |
romseygeek
left a comment
There was a problem hiding this comment.
and LeafWalker needs a reference to LeafBucketCollector
That was the bit I had missed. I think this is good to go then, thanks!
|
@elasticmachine update branch |
|
@elasticmachine update branch |
|
@elasticmachine run elasticsearch-ci/rest-compatibility |
|
@elasticmachine update branch |
|
@elasticmachine update branch |
|
Nice, if my understanding is correct we are going from O(num_docs) lookups in the terms dict of the TSID field to O(num_unique_tsids * num_segments)? So this could be even more than 3x faster on large force-merged shards? |
|
That is a good point. I didn't test it on a large force-merge shards, I will try that. However, I think most of the queries will be executed on hot shards, so realistically speaking this 3x improvement is what we will mostly likely get in real life scenarios. |
|
That will be a great performance improvement for rollups. I will measure its impact when doing a force-merge shards before the shard rollup. |
|
So, I did the test on the rally's tsdb track. The timing has reduced, but not significantly. If with 32 segments I was getting 8469 ms, with 1 segments I started to get 7393 ms. What is unrelated but interesting, while doing this test I also ran cardinality agg by mistake, and I noticed that cardinality execution time grew from 8469 ms on unmerged segments to 23123 ms on a single segment. I repeated the test twice because it was so bizarre and it is definitely a reproducible result. |
|
@not_napolion can probably talk to the cardinality change. He's been
looking at it lately.
…On Mon, Apr 11, 2022, 10:30 PM Igor Motov ***@***.***> wrote:
So, I did the test on the rally's tsdb track. The timing has reduced, but
not significantly. If with 32 segments I was getting 8469 ms, with 1
segments I started to get 7393 ms. What is unrelated but interesting, while
doing this test I also ran cardinality agg by mistake, and I noticed that
cardinality execution time grew from 8469 ms on unmerged segments to 23123
ms on a single segment. I repeated the test twice because it was so bizarre
and it is definitely a reproducible result.
—
Reply to this email directly, view it on GitHub
<#85011 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABUXIVSMWGX65CZA3LE2F3VETN5ZANCNFSM5Q2AI35A>
.
You are receiving this because your review was requested.Message ID:
***@***.***>
|
Adds a place to store information during aggregation execution and use this
context to store the current tsid. It allows us to achieve 3x improvement in
the timeseries aggregation execution speed. In a follow up PR, I would like
to remove the inheritance of BucketCollector from Collector and instead try
wrapping it into a collector when needed. This should prevent us form using
getLeafCollector(LeafReaderContext ctx)method in a wrong context in future.Relates to #74660