bigywater.tech
ZooKeeper · 28

Learner、Follower、Observer 的区别

ZooKeeper 的节点分 leader、follower、observer,前两个投票,observer 不投票。Learner 又是什么?这篇用 3 个投票节点加 2 个 observer 的集群验证:谁算多数派、observer 怎么写、对延迟有什么影响。

observer 不算多数派
3 投票节点停 2 个,即使 2 个 observer 都在也不能写
Learner
follower 与 observer 都向 leader 学习状态,统称 learner
5.95 → 7.21 ms
加 2 个 observer 前后的同步写延迟(同一台机器上的 5 个 JVM)

三种角色

实测 · 本机执行输出
  z28-1 myid 1 → follower
  z28-2 myid 2 → leader
  z28-3 myid 3 → follower
  z28-4 myid 4 → observer
  z28-5 myid 5 → observer
  配置里 observer 的写法: ['peerType=observer', 'server.4=127.0.0.1:7403:7503:observer', 'server.5=127.0.0.1:7404:7504:observer']
  leader 的 zk_followers = None  zk_synced_followers = 2  zk_synced_observers = 2

「learner」是 follower 与 observer 的统称(日志里的 LearnerHandler 就是 leader 为每个 learner 开的处理线程)。

observer 与多数派

实测 · 本机执行输出
  存活节点的 Mode: {'z28-2': '(不服务)', 'z28-4': '(不服务)', 'z28-5': '(不服务)'}
  通过 observer 写入: 失败(没有多数派)

observer 的写

实测 · 本机执行输出
  各节点 Mode: {'z28-1': 'follower', 'z28-2': 'leader', 'z28-4': 'observer', 'z28-5': 'observer'}
  通过 observer 写入:成功(observer 把写请求转给 leader),读回 b'v'

对写延迟的影响

实测 · 本机执行输出
  各轮(3 轮交替):3 投票 = ['5.95', '5.95', '6.96'] | 3 投票 + 2 observer = ['7.09', '7.75', '7.21']
  中位数:3 个投票节点 5.95 ms;3 投票 + 2 observer 7.21 ms

这个差别在不同环境里可能不同(跨机房时 observer 的作用主要是不让远端节点参与投票),本文只测了单机。

分步演示

Observer
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。3 个投票节点 + 2 个 observer 的伪集群;延迟是 3 轮交替的中位数(5 个 JVM 在同一台机器)
    • 没有验证:跨机房场景、observer 的读扩展吞吐(第 29 篇)、observer 选举与重连、observer masters(observerMasterPort)
    京ICP备2026067502号-1京公网安备11010502063487号