TEZ-4757: APPROXIMATE_INPUT_RECORDS over-counts the rows an input will deliver - #540
Conversation
deniskuzZ
commented
Sep 19, 2026
- An announcement carries the source task's output record count so far, not a per-event delta; keep the latest value per input instead of summing events, so a pipelined input's earlier spills are not counted again
- Count an input that wrote no rows in the denominator; leaving it out while numInputs keeps it in the multiplier spread the mean of the inputs that had data over the ones that did not
- Announce from the composite event path too: which path runs depends only on tez.am.shuffle.auxiliary-service.id, so on the Tez shuffle handler the counter was never updated at all
- Multiply before dividing, the mean was truncated first
- Saturate the announced count instead of wrapping it through int, and include large records, which bypass OUTPUT_RECORDS -- the VertexManager event already counts both
- updateApproximateInputRecords takes the input index
- Measured before the fix: 10 inputs, 2 announcing 1000 rows each, read 10,000 instead of 2,000; 4 pipelined events totalling 600 read 450
|
🎊 +1 overall
This message was automatically generated. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
Fixes approximate input record estimation for unordered shuffle inputs.
Changes:
- Track the latest per-input record total, including empty inputs.
- Update both regular and composite event paths.
- Include large records and saturate payload counts.
| File | Description |
|---|---|
| tez-runtime-library/src/test/java/org/apache/tez/runtime/library/common/shuffle/impl/TestShuffleManager.java | Updated as part of this pull request. |
| tez-runtime-library/src/test/java/org/apache/tez/runtime/library/common/shuffle/impl/TestShuffleInputEventHandlerImpl.java | Updated as part of this pull request. |
| tez-runtime-library/src/main/java/org/apache/tez/runtime/library/common/writers/UnorderedPartitionedKVWriter.java | Updated as part of this pull request. |
| tez-runtime-library/src/main/java/org/apache/tez/runtime/library/common/shuffle/impl/ShuffleManager.java | Updated as part of this pull request. |
| tez-runtime-library/src/main/java/org/apache/tez/runtime/library/common/shuffle/impl/ShuffleInputEventHandlerImpl.java | Updated as part of this pull request. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
abstractdog
left a comment
There was a problem hiding this comment.
nice catch, left minor comments only
check also copilot comments please, if they make sense
a03e61c to
9271332
Compare
|
💔 -1 overall
This message was automatically generated. |
9d712ea to
f2121aa
Compare
|
💔 -1 overall
This message was automatically generated. |
f2121aa to
9d9a96c
Compare
|
💔 -1 overall
This message was automatically generated. |
9d9a96c to
3d4487c
Compare
|
💔 -1 overall
This message was automatically generated. |
…l deliver - A report carries the source task's output record count so far, not a per-event delta; keep the latest value per input instead of summing events, so a pipelined input's earlier spills are not counted again - Ignore a report smaller than that input's last one: spill callbacks read the counter and send their event with no lock between, so a stale total can arrive last and would otherwise subtract from the sum - Count an input that wrote no rows in the denominator; leaving it out while numInputs keeps it in the multiplier spread the mean of the inputs that had data over the ones that did not - An output that never started reports 0 rather than nothing, so it joins the denominator instead of being scaled over - Flush the record counters before the final pipelined events read them. An output small enough for one buffer spills only at close, so its DME and its VertexManager event both carried 0 - Report from the composite event path too: which path runs depends only on tez.am.shuffle.auxiliary-service.id, so on the Tez shuffle handler the counter was never updated at all - Scale the mean without forming sum * numInputs, so only the true answer has to fit in a long - num_record is int64, matching the VertexManagerEventPayloadProto field it mirrors. It was int32 while both are filled from long counters, so a task emitting more than 2^31 rows wrapped negative; widening the field alone would only move the loss to the consumer, so the per-input array and the update method carry a long as well. int32 -> int64 is wire compatible in both directions on the same field number - The count includes OUTPUT_LARGE_RECORDS, which bypass OUTPUT_RECORDS; this is what ShuffleUtils.generateVMEvent already sends. Without it a single-partition writer reports 0 for a broadcast of large rows - updateApproximateInputRecords is package-private: it is shuffle internals with one caller in the same package - Measured before the fix: 10 inputs, 2 reporting 1000 rows each, read 10,000 instead of 2,000; 4 pipelined events totalling 600 read 450; a 5-row single-partition pipelined output reported 0
3d4487c to
24d7eeb
Compare
abstractdog
left a comment
There was a problem hiding this comment.
patch looks good, minor comments, mostly about testing
24d7eeb to
a401d9a
Compare
a401d9a to
09fa1a9
Compare
- A negative report is rejected: it neither enters the sum nor marks the input as reported - Writer tests assert against the records the test wrote, with messages naming the event and counter that disagree; the no-data single-partition pipelined case is pinned in the harness that already runs it - Underscore-free test names, javadocs state what is pinned, helper below the tests, imported proto type used unqualified
09fa1a9 to
e22cc8a
Compare
|
🎊 +1 overall
This message was automatically generated. |
|
thank for the review @abstractdog! |

