Adding profiling support for concurrent segment search - #14413
Conversation
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
|
Can you explain why we need two impls? I would have assumed that the |
Hence, I felt we don't need to take the overhead of creating breakdown per segment and then merging it together during response. That being said, eventually we can keep just |
|
Does it make sense to create a separate Can this be implemented as part of the |
|
@jainankitk OK. In my opinion, it's more important to handle the concurrent and non-concurrent cases consistently than to save some overhead when searches are not concurrent. I'd really like non-concurrent search to look and feel like a concurrent search with a single slice running on a SameThreadExecutorService as far as profiling is concerned. So I wouldn't specialize the class hierarchy for concurrent vs. non-concurrent. |
Actually, create one per slice makes lot of sense.
We can always use |
Let me try and see if we can maintain per slice |
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
|
One of the failing check is: I am wondering if there is a workaround for this? One option is to use |
|
You just need to replace |
Signed-off-by: Ankit Jain <akjain@amazon.com>
Ah, my bad! I tried At a high level, I have unified the concurrent/non-concurrent profiling paths as suggested. The
We can probably have map of slices, with key being the |
|
@jpountz - Can you provide your thoughts on above? |
|
I'd have a top-level tree for everything related to initializing the search and combining results (rewrite(), createWeight(), CollectorManager#reduce) and then a list of trees for each slice. Related, it'd be nice if each per-slice object could also tell us about the thread that it ran in and its start time so that we could understand how exactly Lucene managed to parallelize the search. |
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
Signed-off-by: Ankit Jain <akjain@amazon.com>
While working on the code, I realized it is better to have list of slices within the tree itself at each level, instead of repeating the query structure and information across multiple trees. In this approach, we can easily view the tree for specific
Yes, that would be really useful. I have included the threadId as |
|
@jpountz - The code changes are ready for review. For now, I have made changes to accommodate all the timers in While this does not modify ( |
jpountz
left a comment
There was a problem hiding this comment.
Sorry, I had lost track of this PR. I think that my only concern left is how it computes end times by adding the approximate timing to the start time. I'd rather not report it since this profiler doesn't actually compute an end time, but I'd be fine with reporting the sum of approximate timings if we think that it helps.
| } | ||
|
|
||
| /** Retrieve the lucene description of this query (e.g. the "explain" text) */ | ||
| public long getId() { |
There was a problem hiding this comment.
There seems to be a mismatch between javadocs and the method signature.
There was a problem hiding this comment.
I seem to have copied these getters from some existing code and missed editing the javadocs. Let me fix that!
|
|
||
| /** The timing breakdown for this node. */ | ||
| public Map<String, Long> getTimeBreakdown() { | ||
| return Collections.unmodifiableMap(breakdown); |
There was a problem hiding this comment.
You could do the wrapping only once in the constructor?
There was a problem hiding this comment.
Oh yeah, good point! Since the object is immutable
| this.leafLevel = leafLevel; | ||
| } | ||
|
|
||
| public boolean isLeafLevel() { |
There was a problem hiding this comment.
Add some javadocs? I believe that this means that this operation runs on a LeafReader as opposed to the top-level IndexReader?
There was a problem hiding this comment.
Yes, your understanding is correct. Added the javadocs!
|
|
||
| import java.util.List; | ||
|
|
||
| interface QueryLeafProfilerAggregator { |
There was a problem hiding this comment.
I wonder if we actually need this interface since it seems to have a single implementation?
There was a problem hiding this comment.
I was planning to introduce other implementations later, but I guess we can add this interface at that point. Removing for now!
| Arrays.stream(QueryProfilerTimingType.values()).filter(t -> t.isLeafLevel()).toList(); | ||
|
|
||
| /** The accumulated timings for this query node */ | ||
| private final QueryProfilerTimer[] timers; |
There was a problem hiding this comment.
What about using an EnumMap, which will be implemented by an array like this one under the hood?
There was a problem hiding this comment.
Although minor, but EnumMap will initialize the timers for all the possible keys vals = new Object[keyUniverse.length];. It seemed bit unnecessary to me, but we can change if using EnumMap improves the readability.
| sliceStartTime = Math.min(sliceStartTime, timer.getEarliestTimerStartTime()); | ||
| sliceEndTime = | ||
| Math.max( | ||
| sliceEndTime, timer.getEarliestTimerStartTime() + timer.getApproximateTiming()); |
There was a problem hiding this comment.
It doesn't feel right the compute the end time as the start time plus the approximate timing, since operations will often be interleaved. What about reporting the sum of the approximate timings across operation types instead, ie. the value of toTotalTime()?
There was a problem hiding this comment.
Good catch! That was an oversight from my side. Will change this toTotalTime(), which should approximately reflect the consumed cpu time for processing this query
| SLICE, | ||
| // Aggregate leaf level breakdowns based on thread execution | ||
| THREAD | ||
| } |
There was a problem hiding this comment.
Is this actually used? I think that from previous discussions we agreed that SLICE wouldn't work since Lucene doesn't tell us what slice it's in. And I don't see LEAF being used in this PR, only THREAD?
There was a problem hiding this comment.
Yeah, only THREAD is being used for now. I was planning to introduce other implementations like LEAF later, but I guess we can add this enum at that point.
|
This PR has not had activity in the past 2 weeks, labeling it as stale. If the PR is waiting for review, notify the dev@lucene.apache.org list. Thank you for your contribution! |
No worries @jpountz, thanks for the review. Even I was away for a bit, will try to address the comments and push new revision this week. |
Signed-off-by: Ankit Jain <jain.ankitk@gmail.com>
|
This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog label to it and you will stop receiving this reminder on future updates to the PR. |
Signed-off-by: Ankit Jain <jain.ankitk@gmail.com>
|
This PR does not have an entry in lucene/CHANGES.txt. Consider adding one. If the PR doesn't need a changelog entry, then add the skip-changelog label to it and you will stop receiving this reminder on future updates to the PR. |
Signed-off-by: Ankit Jain <jain.ankitk@gmail.com>
|
@jpountz - I have addressed all the comments from earlier review. Are you able to take another look, to help close this out? |
|
This PR has not had activity in the past 2 weeks, labeling it as stale. If the PR is waiting for review, notify the dev@lucene.apache.org list. Thank you for your contribution! |
|
Thanks all for reviewing this PR. Planning to merge this PR by tomorrow, if there is no new feedback. Again, thanks for helping improve this change with your inputs! |
--------- Signed-off-by: Ankit Jain <jain.ankitk@gmail.com>
|
Hi @jainankitk , is |
|
or if we do need to maintain the Thread association, can we store the Thread.id (an int I think) instead of the Thread? |
|
Thanks @dungba88 for trying this out.
The |
|
We don't want to be poking around inside |
That should also be fine. Just adding some sort of |
Description
This code change introduces
AbstractQueryProfilerBreakdownthat can be extended byConcurrentQueryProfilerBreakdownto show query profiling information for concurrent search executionsIssue
Relates to #14375