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