無法刪除節點 Zookeeper: Packet len5391978 is out of range

問題

今天在對Zookeeper進行性能測試, 在/zktest節點下建了16W個節點,每個節點名爲30個字符 然後進行刪除時出現Packet len5391978 is out of range的錯誤, 導致不能獲取節點列表, 也不能刪除節點.

[zk: localhost:2181(CONNECTED) 0] ls /zktest
2016-10-15 04:38:07,650 [myid:] - WARN  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1162] - Session 0x157c679b965000a for server localhost/127.0.0.1:2181, unexpected error, closing socket connection and attempting reconnect
java.io.IOException: Packet len5391978 is out of range!
    at org.apache.zookeeper.ClientCnxnSocket.readLength(ClientCnxnSocket.java:112)
    at org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:79)
    at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:366)
    at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)

stackoverflow

Stackoverflow上有一個解答
Zookeeper CLI failing - IOException Packet is out of range

因爲每次返回信息, 都要先讀取信息的大小, 如果大於默認的4M, 那麼就失敗.

 public static final int packetLen = Integer.getInteger("jute.maxbuffer",
            4096 * 1024);
 protected void readLength() throws IOException {
        int len = incomingBuffer.getInt();
        if (len < 0 || len >= ClientCnxn.packetLen) {
            throw new IOException("Packet len" + len + " is out of range!");
        }
        incomingBuffer = ByteBuffer.allocate(len);
    }

解決方法

可以通過改變jute.maxbuffer這個System properties, 來接收超過4096*1024大小的包.
使用zkCli.sh:在zkCli.sh中加入-Djute.maxbuffer=40960000
$JAVA” “-Dzookeeper.log.dir=${ZOO_LOG_DIR}” “-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}” “-Djute.maxbuffer=40960000” \
-cp “$CLASSPATH” $CLIENT_JVMFLAGS $JVMFLAGS \
org.apache.zookeeper.ZooKeeperMain “$@”

或者在程序中, 生成Zookeeper對象前調用
System.setProperty(“jute.maxbuffer”, “40960000”);

總結

對zookeeper進行操作出現Packet len5391978 is out of range, 是因爲返回的數據包太大, zookeeper爲了提高吞吐量, 對數據包大小進行了限制, 返回數據包大小最大爲4096*1024, 而節點最大數據量則爲1M

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章