[fix][metadata]Solve the problem of broker log looping and request failure stagnation after network packet loss recovery - #26254
Conversation
|
Our team used mirrored images of the old and new code to inject 90% packet loss into each broker pod for half an hour. Without the fix, even after the broker network recovered, the logs would keep looping and the broker would experience prolonged connection interruptions. With the fix applied, the broker traffic recovered quickly after the network was restored. Therefore, I believe this PR is still valuable. |
|
Thanks for the detailed investigation and the clear explanation of the recovery loop. Preventing However, I think the expanded state handling should be completed before merging. The scheduled For example:
I suggest updating the probe so that it preserves the actual ZooKeeper state:
Please also add deterministic tests for the scheduled probe path, for example:
The current tests only invoke If the intention is to keep this PR narrowly focused, another reasonable option is to handle only the original |
Motivation
During ZooKeeper session-expired recovery, the broker can close the old ZooKeeper handle and create a new
ZooKeeper client. The old handle may emit
KeeperState.Closedas part of this local close sequence.Before this change,
ZKSessionWatchertreated every ZooKeeperKeeperStateother thanExpiredandDisconnectedas a successful reconnection. This meansKeeperState.Closedcould be translated intoReconnectedandSessionReestablished, even thoughClosedonly means the old ZooKeeper handle was closed. Itdoes not prove that a new session has connected to the ZooKeeper quorum.
This matters because
ReconnectedandSessionReestablishedare not passive notifications in Pulsar. They triggermetadata recovery work, including persistent watch recreation, resource lock revalidation, and leader election
revalidation. If these events are published before the new ZooKeeper session is actually healthy, the broker can start
recovery work against an unstable or expired session.
In a severe network-loss scenario, this can become a recovery storm:
KeeperState.Closed.Closedis incorrectly treated as a successful reconnection.Reconnected/SessionReestablished.The logs will output in a loop as follows:
The fix is to make the state machine explicit: only
KeeperState.SyncConnectedshould be treated as a successfulreconnection.
Modifications
ZKSessionWatcherstate handling so onlyKeeperState.SyncConnectedpublishesReconnectedandSessionReestablished.Disconnectedcontinues to wait for reconnection.ConnectedReadOnlywaits for a writable quorum connection instead of treating the read-only connection as fullyrecovered.
AuthFailedmarks the metadata session as lost.SaslAuthenticatedis logged without publishing recovery events.Closedis logged without changing the metadata session state.ZKSessionWatcherTestto verify thatClosedand other non-SyncConnectedstates do not publishReconnectedorSessionReestablishedafterSessionLost.ZKSessionWatcher.Verifying this change
This change added tests and can be verified as follows:
ZKSessionWatcherstate transitions.ZKSessionTest.Commands run locally:
Does this pull request potentially affect one of the following parts: