bigywater.tech
ZooKeeper · 49

集群成员管理

ZooKeeper 集群的「成员」是怎么定义的?配错了会怎样?这篇用静态配置的集群验证几种最常见的成员配置错误:myid 不在列表里、成员列表不一致、名单外的节点自己加入。

server.N + myid
成员关系 = 配置里的列表 + 每个节点的 myid 文件
退出码 1
myid 不在 server 列表里,启动即失败
名单外的节点
能连上并同步,但不参与多数派

成员列表

实测 · 本机执行输出
  z49-1 myid=1:['server.1=127.0.0.1:7400:7500:participant', 'server.2=127.0.0.1:7401:7501:participant', 'server.3=127.0.0.1:7402:7502:participant']
  z49-2 myid=2:['server.1=127.0.0.1:7400:7500:participant', 'server.2=127.0.0.1:7401:7501:participant', 'server.3=127.0.0.1:7402:7502:participant']
  z49-3 myid=3:['server.1=127.0.0.1:7400:7500:participant', 'server.2=127.0.0.1:7401:7501:participant', 'server.3=127.0.0.1:7402:7502:participant']

myid 配错

实测 · 本机执行输出
  退出码: 1
  日志: Starting quorum peer, myid=9
  日志: Unexpected exception, exiting abnormally
  日志: java.lang.RuntimeException: My id 9 not in the peer list
  日志: Exiting JVM with code 1

列表不一致

实测 · 本机执行输出
  各节点 Mode: {'z49m-1': 'follower', 'z49m-2': 'leader', 'z49m-3': '不服务'}
  节点 3 的 conf 成员: []

这是我构造的一种不一致(少一个成员);其它的不一致(端口写错、地址不同)没有逐个测。

名单外的节点

实测 · 本机执行输出
  原 3 个节点 Mode: {'z49n-1': 'follower', 'z49n-2': 'leader', 'z49n-3': 'follower'}
  新节点(myid=4)Mode: follower
  原节点 leader 的 zk_synced_followers = 3
  新节点 conf 里的 server 数: 4 | 原节点 conf 里的 server 数: 3
  停掉原来的两个 follower,只剩原 leader + 这个「不在名单里」的新节点(2/3 个名单内成员里只剩 1 个):写入 失败(它没有被算进多数派)
  此时各节点 Mode: {'z49n-2': '不服务', 'z49n-4': '不服务'}

这是一个值得警惕的现象:它没有破坏一致性(多数派仍只按名单内的节点计算),但意味着配置错误的节点可能静悄悄地连上集群、读到数据。动态配置(第 50 篇)用 reconfig 来管理成员变化,不依赖这种「自己加入」。

分步演示

集群成员
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。静态配置伪集群;每个场景一个新实例
    • 没有验证:成员的 DNS 名与 IP 变化、成员端口冲突、observer 成员的配置错误(第 28 篇)、动态配置下的成员管理(第 50、51 篇)
    京ICP备2026067502号-1京公网安备11010502063487号