ZooKeeper ZAB 协议深度解析
候选人小李在面试美团 P6 时,面试官问:"ZooKeeper 的 Leader 选举是怎么进行的?如果 Leader 挂了,新 Leader 是怎么选出来的?"
小李说:"用 ZooKeeper 的 Leader 选举..."面试官追问:"那选举的具体算法是什么?zxid 和 epoch 分别代表什么?"
小李摇头。
【面试官心理】 ZAB 协议是 ZooKeeper 一致性的核心,但大多数候选人只知道"ZooKeeper 是 CP 系统"。能说清楚 Leader 选举算法、zxid 的作用、崩溃恢复流程的候选人,说明他对分布式一致性有深入理解。这种候选人在我这里是 P6+ 的加分项。
一、ZAB 协议概述 🔴
1.1 ZAB 是什么
ZAB(ZooKeeper Atomic Broadcast)是 ZooKeeper 的原子广播协议,它解决了三个问题:
- 原子性:消息要么全部同步,要么全部不同步
- 一致性:所有 Follower 的状态最终一致
- 有序性:消息按 Leader 提出的顺序执行
1.2 ❌ 错误示范
候选人原话:"ZAB 就是 Paxos 算法在 ZooKeeper 中的实现。"
问题诊断:
- 混淆了 ZAB 和 Paxos 的关系
- ZAB 是专门为 ZooKeeper 设计的,不是 Paxos
- ZAB 有 Leader 概念,Paxos 没有
【面试官心理】 ZAB 和 Paxos 的关系是经典面试题。能说清楚 ZAB 是为 ZooKeeper 设计的、专注于"主备"模式的协议,而不是通用的一致性算法,才是真正理解了 ZooKeeper 的设计哲学。
二、ZAB 的两种运行模式 🟡
2.1 模式切换图
2.2 状态说明
三、Leader 选举机制 🟡
3.1 选举的触发时机
- 服务启动时:所有服务都是 Looking 状态,开始选举
- Leader 崩溃时:Leader 无法响应,Follower 变为 Looking
- 过半 Follower 无法连接 Leader:触发重新选举
3.2 投票的数据结构
投票优先级(按以下顺序比较):
3.3 Fast Leader Election 算法
投票 PK 的逻辑:
3.4 zxid 的作用
zxid(ZooKeeper Transaction ID)是全局递增的事务编号:
zxid 的含义:
- 高 32 位(epoch):Leader 的任期号,每次选举递增
- 低 32 位(counter):事务计数器,每个事务递增
zxid 为什么越大越优:
- 高 epoch 表示更新的 Leader:说明数据更新
- 高 counter 表示数据更完整:没有丢失事务
- 新 Leader 必须包含所有已提交的事务:通过 zxid 保证
四、消息广播(Broadcast)🟡
4.1 两阶段提交
ZAB 的消息广播是一个简化版的 2PC:
4.2 为什么是过半确认
ZooKeeper 的过半原则:
- 写入:需要过半节点确认(3节点集群需要2个确认)
- 读取:可以读任意节点(最终一致)
- 选举:需要过半节点同意
过半原则的好处:
4.3 Observer 节点
Observer 不参与投票,只同步 Leader 的数据:
使用场景:
- 跨数据中心部署:Observer 可以部署在远距离数据中心,减少延迟
- 读多写少:增加 Observer 提高读取吞吐量
五、崩溃恢复(Recovery)🟡
5.1 什么时候需要恢复
Leader 崩溃后,需要恢复两个保证:
- 已提交的事务必须被所有服务器接受
- 未提交的事务必须被丢弃
5.2 恢复流程
5.3 数据同步的三种情况
六、CAP 定位 🟢
6.1 ZooKeeper 是 CP 系统
ZooKeeper 保证强一致性(CP):
为什么 ZooKeeper 是 CP:
- 一致性:所有 Follower 的状态最终一致
- 分区容错:支持网络分区
- 牺牲可用性:Leader 崩溃时,服务不可用,直到新 Leader 选出
6.2 与 Eureka 的对比
Eureka 的 AP 特性意味着:当你写数据时,即使某些节点没收到数据,客户端仍然可以读到旧数据。但 ZooKeeper 的 CP 特性保证了:如果 Leader 说数据已提交,所有节点都能读到。
七、生产避坑
7.1 常见翻车点
- 偶数节点部署:2 节点 ZooKeeper 无法容忍任何节点故障
- Session 超时配置过长:Leader 崩溃后需要更长时间恢复
- 写入压力过大:ZooKeeper 不适合高并发写入
- 网络分区导致脑裂:过半原则可以防止脑裂,但需要正确配置
7.2 运维建议
ZooKeeper 的写入是串行的(通过 Leader),高并发写入场景下会成为瓶颈。注册中心场景下写入量不大,但如果你的场景有大量动态配置更新,需要评估 ZooKeeper 的承受能力。
【面试官心理】 ZAB 协议是 ZooKeeper 一致性的核心。能说清楚 Leader 选举的投票优先级(electionEpoch > zxid > serverId)、消息广播的两阶段提交、崩溃恢复的数据同步流程的候选人,说明他对分布式一致性有深入理解。这种候选人在我这里是 P6+ 的加分项。