Repository navigation
[fix][meta] Split ZooKeeper read batches rejected by the multiRead limits - #27353
Merged
lhotari merged 2 commits intoNov 5, 2026
Merged
Conversation
…mits ZooKeeper 3.9.7 rejects a multiRead request over multiRead.maxOps or multiRead.maxResponseBytes with BADARGUMENTS, which failed every read in the batch. Batches are formed from estimated response sizes, so a batch can exceed the limits even though each of its reads is valid. Halve a rejected read batch and retry the parts. A rejected single read fails on its own, so a batch of n reads makes at most 2n - 1 requests. Update the guidance for the limits to match this behavior. Assisted-by: Claude Code/claude-opus-5-5
lhotari
requested review from
Denovo1998,
Technoboy-,
codelipenghui,
dao-jun,
merlimat and
nodece
November 4, 2026 12:32
2 of 11 tasks
Denovo1998
requested changes
Nov 4, 2026
…arning Each rejected part of a split read batch logged its own warning, so a batch of n reads could log up to n - 1 warnings. Log the rejection of the original batch at WARN and the rejections of its parts at TRACE. Assisted-by: Claude Code/claude-opus-5-5
Denovo1998
approved these changes
Nov 5, 2026
nodece
approved these changes
Nov 5, 2026
codelipenghui
approved these changes
Nov 5, 2026
codelipenghui
left a comment
Contributor
There was a problem hiding this comment.
Code Review approval for commit 16b3920.
Summary:
No actionable findings identified within the reviewed scope.
The read-only splitting approach is bounded, preserves write behavior, and retains ZooKeeper’s limits. Disabling the fallback reproduced both rejection modes; restoring it resolved them. The final focused run passed 36 tests. An earlier session-event ordering failure remains an inconclusive validation limitation. All temporary source edits were restored; HEAD remains 16b392070ebd175b99faf2dc06bfe5cf9d08351d.
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
This is the follow-up to this review comment on #27343.
ZooKeeper 3.9.7 added the
multiRead.maxOps(default 1000) andmultiRead.maxResponseBytes(default 64 MiB) server limits. AmultiReadrequest over either limit is rejected as a whole withBADARGUMENTS, andZKMetadataStorefailed every read in the batch.ZKMetadataStoreBatchStrategyforms batches from estimated response sizes, so a batch can go over the limit even though each read in it is valid. Withjute.maxbuffer=41943040(40 MiB) and the default limits, two 35 MiB reads in one batch fail withBadArguments. On ZooKeeper 3.9.6 the same batch recovered, because it failed withCONNECTIONLOSSand the reads were retried individually.The guidance added in #27343 was also wrong. It said that the response limit only has to be larger than
jute.maxbuffer, but the case above fails with ajute.maxbufferwell below the limit, and raising the limit abovejute.maxbufferdoesn't prevent it for larger batches.Modifications
ZKMetadataStore: when a read batch of two or more operations is rejected withBADARGUMENTS, halve it and retry both parts.GETandGET_CHILDRENoperations are split. Write batches behave as before.multiRead.maxOpstoo low doesn't turn a large batch into one request per read.conf/zookeeper.conf,conf/global_zookeeper.conf,conf/broker.conf,conf/standalone.confandServiceConfiguration.multiRead.maxOpsat least as large asmetadataStoreBatchingMaxOperationsnow only avoids extra requests.multiRead.maxResponseBytesmust be larger than the response to any single read, such as the largest z-node's data or children list.TestZKServer: addedsetMultiReadLimitsso that tests can change the limits on the running server.The server limits stay enabled with their defaults. A single read over
multiRead.maxResponseBytesstill fails, even ifjute.maxbufferwould allow it.Verifying this change
This change added tests and can be verified as follows:
ZKMetadataStoreMultiReadLimitsTest, which runs against a real ZooKeeper server and covers a batch over the response limit, a batch over the operation count limit, and a single oversized read failing without affecting the other reads in its batch. All 3 tests fail with the fix disabled and pass with it.jute.maxbuffer=41943040, default limits andmetadataStoreBatchingMaxOperations=2, with 3 reads. With the fix disabled, the 2 reads in the first batch fail withBadArguments. With the fix, all 3 succeed.MetadataStoreBatchingTest,ZKSessionTestandZKMetadataStoreBatchIOperationTestpass locally.MetadataStoreTestpasses locally except fortestGetChildren[ZooKeeper]when run with retries off. That test also failed the same way on ZooKeeper 3.9.6 during the work on [fix][sec] Upgrade ZooKeeper to 3.9.7 to address several CVEs #27343, so this change doesn't cause it.Not covered: there's no test that write batches aren't split, because I couldn't readily get the server to reject a write batch with
BADARGUMENTS. The full broker suite and the integration tests were not run locally.Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes