Repository navigation
Conversation
swuferhong
left a comment
There was a problem hiding this comment.
Hi, @morazow thanks for your contribution, I left one comment:
| if (!targetReplicas.contains(currentLeader)) { | ||
| // The first target replica is the planned leader (see GoalOptimizerUtils#getDiff), so | ||
| // re-elect also when the current leader stays in the target replicas but is not first. | ||
| if (currentLeader != targetReplicas.get(0)) { |
There was a problem hiding this comment.
This fixes the missing leader election, but combined replica-and-leader reassignment still completes before the planned leader acknowledges the final state.
onBucketReassignment(..., true) sends asynchronous NotifyLeaderAndIsr requests and then immediately calls finishRebalanceTask(..., COMPLETED). The existing ACK-based completion check only applies to leader-only plans.
I reproduced this on 9266dec: after Phase A, hold server 1's notification responses and submit the ISR catch-up for [0,1,3] -> [1,0,2]. The metadata leader becomes 1, but the task is already COMPLETED while those responses remain pending.
Could we complete this flow before merging, as required by #3869? Completion should wait for a successful ACK from the planned leader for the final assignment and epoch. Earlier-phase/stale responses must not satisfy that condition, and failures, timeout, or coordinator restart must leave the task recoverable.
Please extend the regression test to hold the final target-leader ACK and assert that the task remains REBALANCING until that ACK is released.
There was a problem hiding this comment.
Hello @swuferhong ,
I see it now, I had to understand first on the phase B part of the rebalance.
You PR on #3860 already addressed this, right?
I'd suggest then you can add the part for if (currentLeader != targetReplicas.get(0)) {, then it will also fix the flakiness resulting from it. Please feel free to move the tests to your PR.
Then I will close this PR 🤝
swuferhong
left a comment
There was a problem hiding this comment.
Hi, @morazow thanks for your contribution, I left one comment:
|
Thanks @swuferhong for the review, checking and addressing today 🤝 |
0715d18 to
3bd65c5
Compare
A rebalance plan that moves a replica and the leadership of the same bucket encodes the target leader as the first target replica, for example [2, 0, 1] -> [3, 2, 1] with new leader 3. After the adding replicas caught up, the coordinator re-elected a leader only when the current leader was removed from the target replicas. When the old leader stayed, it kept leadership and the task was still marked COMPLETED, so a server could end the rebalance with fewer leaders than planned. This made RebalanceITCase#testRebalanceForLogTable fail with 0 leaders on one server. Re-elect whenever the current leader is not the first target replica. This closes apache#4622.
3bd65c5 to
1034d6d
Compare
…ase B Cover the remaining apache#3869 acceptance criteria for the combined replica and leader reassignment: - An ISR change while the task waits for the planned leader's ACK does not run phase B again. - A failed ACK keeps the task REBALANCING until the task timeout. - A coordinator restart at each phase B boundary resumes the move and completes only on the planned leader's ACK.
1034d6d to
b529533
Compare
Purpose
Linked issues: close #4622, close #3869
RebalanceITCase#testRebalanceForLogTableintermittently fails because one tablet server ends a completed rebalance with 0 leaders. The test exposes a real coordinator bug: a planned leadership move is dropped when the same bucket also has a replica move (#4622). As discussed with @swuferhong, this PR also makes that combined move wait for the planned leader's acknowledgement before the task completes (#3869).Brief change log
The goal optimizer encodes the target leader as the first target replica (
GoalOptimizerUtils#getDiff). A plan can move a replica and the leadership of the same bucket, for example:Phase A - elect the planned leader. After the adding replicas catch up,
CoordinatorEventProcessor#maybeReassignedBucketLeaderIfRequiredre-elected a leader only when the current leader was not in the target replicas. Here the old leader 2 stays, so no election ran. Server 2 kept leadership and the task was still markedCOMPLETED. The coordinator now re-elects whenever the current leader is not the first target replica.Phase B - wait for the planned leader's ACK. The combined move sent asynchronous
NotifyLeaderAndIsrrequests and then marked the taskCOMPLETEDin the same call. Only leader-only plans waited for an ACK, and that check looked only at the server id.RebalanceManagerrecords the bucket epoch the planned leader must acknowledge.CoordinatorRequestBatchpasses the bucket epoch each request sent to the response event, because the response carries no epoch.REBALANCINGuntil the existing task timeout. After a coordinator restart, ZooKeeper already holds the target replicas, so the recovered plan runs the leader-only path, which also waits for the ACK.Tests
CoordinatorEventProcessorTest:testBucketReassignmentMovesLeaderWhenOldLeaderStaysInReplicas: plan[0, 1, 3] -> [1, 0, 2]with new leader 1. It holds the planned leader's final ACK and releases all earlier responses, then checks that an ISR change sends no new requests. The task staysREBALANCINGuntil the ACK is released, then completes with leader 1 and replicas[1, 0, 2].testBucketReassignmentWaitsForTimeoutWhenPlannedLeaderAckFails: a failed ACK keeps the taskREBALANCING, and the task timeout then moves it toTIMEOUT.testBucketReassignmentWithLeaderChangeResumesAfterCoordinatorRestart: parameterized over four phase B boundaries (before leader election, after election, after the ISR shrink, after the assignment update). Each case completes only on the planned leader's ACK.Red-green: reverting each part of the fix makes these tests fail. Phase B finishing immediately fails 5 tests, dropping the epoch check fails 2, and dropping the ISR-change guard fails 1.
Runs:
CoordinatorEventProcessorTest(40),RebalanceManagerTest(5) andRebalanceManagerITCase(2) pass.RebalanceITCasepassed 10 of 10 runs. Before the fix, the unmodified test failed 1 in 8 local runs.API and Format
No.
Documentation
No.
🤖 Generated with Claude Code