Optimize how we merge multiple operatorStats#24414
Conversation
dfcc4ca to
a8ecf10
Compare
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
727cf06 to
6808005
Compare
|
Thanks for the release note! Rephrasing suggestions to follow the Order of changes in the Release Notes Guidelines: |
|
@arhimondr feel free to take another look. Thank you so much for all the awesome suggestionsl |
arhimondr
left a comment
There was a problem hiding this comment.
Thank you for following up. Looks good to me % comments
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/execution/StageExecutionInfo.java
Outdated
Show resolved
Hide resolved
1d78017 to
a3c6221
Compare
presto-main/src/main/java/com/facebook/presto/operator/OperatorStats.java
Outdated
Show resolved
Hide resolved
presto-main/src/main/java/com/facebook/presto/operator/OperatorStats.java
Outdated
Show resolved
Hide resolved
| for (OperatorStats operator : operators) { | ||
| operatorSummaries.compute(operator.getOperatorId(), (operatorId, summaryStats) -> summaryStats == null ? operator : summaryStats.add(operator)); | ||
| } | ||
| operators.stream().collect(Collectors.groupingBy(OperatorStats::getOperatorId)) |
There was a problem hiding this comment.
This will only have one OperatorStats per operator. Probably we can keep the loop and avoid groupingBy.
There was a problem hiding this comment.
Yep. I should have double checked on that. Thanks for catching it.
| } | ||
| operatorSummaries.put(operatorId, combined); | ||
| } | ||
| runningOperators.asMap().forEach((operatorId, runningStats) -> { |
There was a problem hiding this comment.
Consider using the same approach with merge + toImmutableList)
There was a problem hiding this comment.
Good point. Did not realize this part is rather similar to StageExecutionStats
1cedaea to
749d60b
Compare
| int stageExecutionId = first.getStageExecutionId(); | ||
| int pipelineId = first.getPipelineId(); | ||
| PlanNodeId planNodeId = first.getPlanNodeId(); | ||
| String operatorType = first.getOperatorType(); |
There was a problem hiding this comment.
@arhimondr one issue with "0" based initial value is we dont have a starting value for those ids but need to grab them from the first item of the collections passed in. This is safe since we check its emptiness right above. Let me know what you think.
6ea95c3 to
cec07cd
Compare
arhimondr
left a comment
There was a problem hiding this comment.
Very good. Thank you for the follow up.
Looks great to me % two small questions
| ListMultimap<Integer, OperatorStats> runningOperators = ArrayListMultimap.create(); | ||
| ImmutableList.Builder<DriverStats> drivers = ImmutableList.builderWithExpectedSize(driverContexts.size()); | ||
| // Make deep copy of each list | ||
| ConcurrentMap<Integer, List<OperatorStats>> operatorStatsById = this.operatorStatsById.entrySet().stream() |
There was a problem hiding this comment.
Does it have to be ConcurrentMap? Have you considered a simple Map and the toMap collector?
There was a problem hiding this comment.
You are absolutely correct. It does not need to be concurrentMap. Regular map will do the job.
| ImmutableList.Builder<DriverStats> drivers = ImmutableList.builderWithExpectedSize(driverContexts.size()); | ||
| // Make deep copy of each list | ||
| ConcurrentMap<Integer, List<OperatorStats>> operatorStatsById = this.operatorStatsById.entrySet().stream() | ||
| .collect(toConcurrentMap(Map.Entry::getKey, e -> new ArrayList<>(Arrays.asList(e.getValue())))); |
There was a problem hiding this comment.
Do you need to have an extra new ArrayList<>(...)? Would Arrays.asList(e.getValue()) alone work?
There was a problem hiding this comment.
Yeah, it needs to be new ArrayList<> since Arrays.asList(e.getValue()) will create a immutable resizable list but we need it be mutable so we can add item to it later on here
for (OperatorStats operatorStats : driverStats.getOperatorStats()) {
operatorStatsById.computeIfAbsent(operatorStats.getOperatorId(), k -> new ArrayList<>()).add(operatorStats);
}
There was a problem hiding this comment.
The standard JDK Arrays.asList returns a mutable ArrayList: https://github.com/openjdk/jdk21/blob/master/src/java.base/share/classes/java/util/Arrays.java#L4222
Is this the JDK Arrays.asList used here? Or is there one in Guava?
There was a problem hiding this comment.
It is from standard JDK. It gives the following exception because the Arrays.asList call "returns a fixed-size list backed by the specified array." (so basically a view of the array) We can modify existing elements but can not resize the list. I should have said it is mutable by not resizable. Sorry about the confusion and let me know if there is a better way. Really appreciate all the discussion. Learned a lot!

There was a problem hiding this comment.
I didn't know that. Thank you for the explanation
cec07cd to
35c51ba
Compare
## Description 1. this pr re-introduce the #24414 , which cause a sev where written partition was not logged. The bug is a corner case, where while merging only one single non-mergeable operatorInfo, the old code will NOT perform any merge operation (since the add operation will only get invoke when the second operator stats shows up) and give back the operator info itself while #24414 will actually kick off a merge and gives null result. 2. This pr reintroduce #24414 and handles this corner case and also added specific unit tests for this scenario. ## Motivation and Context 1. re-introduce #24414 ## Impact <!---Describe any public API or user-facing feature change or any performance impact--> ## Test Plan 1. verifier runs log written partition correctly: <img width="1469" alt="Screenshot 2025-04-15 at 17 13 08" src="https://github.com/user-attachments/assets/f7c84a8f-7381-411a-95d1-15b075870b83" /> ## Contributor checklist - [ ] Please make sure your submission complies with our [contributing guide](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md), in particular [code style](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#code-style) and [commit standards](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#commit-standards). - [ ] PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced. - [ ] Documented new properties (with its default value), SQL syntax, functions, or other functionality. - [ ] If release notes are required, they follow the [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines). - [ ] Adequate tests were added if applicable. - [ ] CI passed. ## Release Notes Please follow [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines) and fill in the release notes below. ``` == RELEASE NOTES == General Changes * Improve how we merge multiple operator stats together. * Improve metrics creation by refactoring local variables to a dedicated class. ```
## Description 1. this pr re-introduce the prestodb#24414 , which cause a sev where written partition was not logged. The bug is a corner case, where while merging only one single non-mergeable operatorInfo, the old code will NOT perform any merge operation (since the add operation will only get invoke when the second operator stats shows up) and give back the operator info itself while prestodb#24414 will actually kick off a merge and gives null result. 2. This pr reintroduce prestodb#24414 and handles this corner case and also added specific unit tests for this scenario. ## Motivation and Context 1. re-introduce prestodb#24414 ## Impact <!---Describe any public API or user-facing feature change or any performance impact--> ## Test Plan 1. verifier runs log written partition correctly: <img width="1469" alt="Screenshot 2025-04-15 at 17 13 08" src="https://github.com/user-attachments/assets/f7c84a8f-7381-411a-95d1-15b075870b83" /> ## Contributor checklist - [ ] Please make sure your submission complies with our [contributing guide](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md), in particular [code style](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#code-style) and [commit standards](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#commit-standards). - [ ] PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced. - [ ] Documented new properties (with its default value), SQL syntax, functions, or other functionality. - [ ] If release notes are required, they follow the [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines). - [ ] Adequate tests were added if applicable. - [ ] CI passed. ## Release Notes Please follow [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines) and fill in the release notes below. ``` == RELEASE NOTES == General Changes * Improve how we merge multiple operator stats together. * Improve metrics creation by refactoring local variables to a dedicated class. ```
Description
Motivation and Context
Impact
Test Plan
Contributor checklist
Release Notes
Please follow release notes guidelines and fill in the release notes below.