bigywater.tech
ZooKeeper · 24

Jute 最大消息大小

jute.maxbuffer 是 ZooKeeper 里最容易被忽略、又最容易让人困惑的参数:超过它,你看到的只是 ConnectionLoss。这篇找出它的准确临界点、服务端日志里的证据,以及服务端与客户端各自管什么。

1048575
jute.maxbuffer 默认值(字节),限制整个请求包
Len error
请求超限时服务端日志里的错误,客户端只看到 ConnectionLoss
两端都要设
服务端限制请求大小,Java 客户端限制响应大小

默认值的临界点

实测 · 本机执行输出
  create 数据  1048000 字节 → OK
  create 数据  1048500 字节 → OK
  create 数据  1048560 字节 → ConnectionLoss
  create 数据  1048576 字节 → ConnectionLoss
  create 数据  2097152 字节 → ConnectionLoss
  服务端日志: ['java.io.IOException: Len error. A message from /127.0.0.1:59340 with advertised length of 1048616 is either a malformed message or too large to process (length is greater than jute.maxbuffer=1048575)', 'java.io.IOException: Len error. A message from /127.0.0.1:59343 with advertised length of 1048632 is either a malformed message or too large to process (length is greater than jute.maxbuffer=1048575)']

数据 1048500 字节还能成功,1048560 就失败,差的几十字节是请求头与路径。

调大服务端

实测 · 本机执行输出
  kazoo 写 3 MiB 到 4 MiB 上限的服务端 → 成功
  kazoo 读回长度: 3145728 (kazoo 没有按 jute.maxbuffer 检查响应大小)
  官方 Java 客户端(默认 jute.maxbuffer)执行 stat /b3(不读数据)→ ['dataLength = 3145728']
  官方 Java 客户端(默认 jute.maxbuffer)执行 get /b3 → 输出 125 字符: 'WatchedEvent state:Disconnected type:None path:null zxid: -1\nKeeperErrorCode = ConnectionLoss for /b3\nExiting JVM with code 1'
  同样命令,客户端也设 -Djute.maxbuffer=4194304 → 输出 3145728 字符(数据 3145728 字节)

两端一起调

实测 · 本机执行输出
  写 5 MiB 到 4 MiB 上限的服务端 → ConnectionLoss

官方文档的建议是调大这个值前先想想是不是该换设计:大数据放进 ZooKeeper 本身就不合适(第 1、22 篇)。

分步演示

jute.maxbuffer
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。服务端 JVM 参数 -Djute.maxbuffer=4194304 通过 Node 的 jvm 参数传入;Java 客户端用官方 ZooKeeperMain;kazoo 2.11.0
    • 没有验证:集群里只有部分节点调大的后果、Netty 与 NIO 的差异、其它相关参数(如 zookeeper.large_request_max_bytes)、数据压缩
    京ICP备2026067502号-1京公网安备11010502063487号