Fix Kinesis empty segment commit loop after shard merge - #19086
Conversation
After shard merge/split, fail-closed end-of-shard probes treated closed drained shards as still live, so the controller recreated empty consuming segments forever and blocked child shards. Closed-shard short-circuit and empty-only probes now mark the parent ended.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #19086 +/- ##
=========================================
Coverage 65.47% 65.47%
- Complexity 1421 1430 +9
=========================================
Files 3426 3426
Lines 217315 217354 +39
Branches 34509 34517 +8
=========================================
+ Hits 142283 142318 +35
- Misses 63513 63517 +4
Partials 11519 11519
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Ready for review — all required CI checks are green on this PR. Issue: #17209 Could the following folks take a look when convenient? Formal GitHub "Request review" is unavailable from a fork contributor account on Thank you! |
There was a problem hiding this comment.
Pull request overview
Fixes a controller-side reliability issue in the Kinesis stream ingestion path where, after shard split/merge, closed parent shards could be treated as still-live and repeatedly recreated as empty consuming segments (blocking child shard admission).
Changes:
- Add closed-shard short-circuiting based on checkpoint sequence number vs.
endingSequenceNumber, and revise the end-of-shard probe loop to treat empty-only probes on closed shards as “ended” (with special handling for throttle/timeout empties). - Introduce a dedicated max-empty-probe constant and a time/attempt budget to prevent unbounded probing behavior.
- Update and extend
KinesisStreamMetadataProviderTestto cover the fixed behavior (parent removal, child admission, SN short-circuit, throttle/timeout behavior).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
pinot-plugins/pinot-stream-ingestion/pinot-kinesis/src/main/java/org/apache/pinot/plugin/stream/kinesis/KinesisStreamMetadataProvider.java |
Changes end-of-shard detection logic for closed shards to avoid reopening parents and triggering infinite empty-commit loops. |
pinot-plugins/pinot-stream-ingestion/pinot-kinesis/src/test/java/org/apache/pinot/plugin/stream/kinesis/KinesisStreamMetadataProviderTest.java |
Updates existing tests and adds new cases validating closed-shard handling, short-circuiting, and throttle/timeout probe behavior. |
| boolean likelyTransientEmpty = fetchElapsedMs >= (fetchTimeoutMs * 3L / 4L); | ||
| if (!likelyTransientEmpty) { | ||
| emptyProbes++; | ||
| } |
Why
After a Kinesis shard merge/split, servers correctly stop with
endOfPartitionGroupand commit. The controller then re-probed end-of-shard viaKinesisStreamMetadataProvider.consumedEndOfShard. On max empty non-EOP polls (including rate-limit empties), the provider assumed the shard was still live. That recreated a new consuming segment on the closed parent, which immediately committed empty — forever — and blocked child-shard admission (shardsEnded).This is a production reliability bug for any realtime table on Kinesis that rescales shards.
Impact
How
In
KinesisStreamMetadataProvider:endingSequenceNumber.Test plan
KinesisStreamMetadataProviderTest(closed shard + empty-only probes ⇒ parent removed; sequence short-circuit; child admission after parent end)../mvnw -pl pinot-plugins/pinot-stream-ingestion/pinot-kinesis -am -Dtest=KinesisStreamMetadataProviderTest -Dsurefire.failIfNoSpecifiedTests=false testRelated
fixes: #17209
Reviewers
Suggested: maintainers familiar with stream ingestion / Kinesis
Was generative AI tooling used to co-author this PR?
Generated-by: Grok Build (xAI)