← 返回题目列表

ZAB 协议是什么?ZooKeeper 是怎么保证一致性的?

高频 困难 第 16 / 26 题 更新于 2026/07/28
ZABZooKeeper原子广播分布式一致性

简化版

ZAB 是 ZooKeeper 使用的原子广播协议,用来保证多个 ZooKeeper 副本按相同顺序处理事务请求。它采用 Leader-Follower 模型,写请求由 Leader 转换成事务提案,广播给 Follower,超过半数确认后提交。ZAB 重点保证事务顺序一致、Leader 崩溃后已提交事务不丢、未提交事务不会被错误提交。

详细版

ZAB 有两个核心模式:崩溃恢复和消息广播。集群启动或 Leader 故障后进入恢复模式,先选出新 Leader,并让新 Leader 同步多数派中最新的事务历史。恢复完成后进入广播模式,Leader 接收写请求,为事务分配 zxid,再广播 Proposal。多数 Follower ACK 后,Leader 发送 Commit,所有节点按 zxid 顺序应用事务。

zxid 是 ZAB 的关键标识,通常包含 epoch 和递增计数。epoch 表示 Leader 任期,计数表示该任期内事务顺序。新 Leader 必须拥有足够新的事务历史,才能继续对外服务。

ZooKeeper 的强一致写来自 ZAB 的多数派提交和顺序广播。读请求默认可以在 Follower 本地读,因此可能读到旧数据;如果需要读到最新状态,可以使用 sync 等机制。

完整版教学

一、ZAB 的定位

ZAB 全称 ZooKeeper Atomic Broadcast,是 ZooKeeper 为复制事务日志设计的原子广播协议。它不是通用 RPC 协议,而是 ZooKeeper 保证元数据一致性的核心。ZooKeeper 中创建节点、删除节点、更新数据、修改 ACL 这类写操作都会变成事务,经过 ZAB 复制到多数节点,再按相同顺序应用。

原子广播强调两点:要么足够多节点最终看到同一条消息,要么这条消息不被当作已提交;并且所有节点看到消息的顺序一致。对 ZooKeeper 这种协调服务来说,顺序特别重要,因为后面的事务可能依赖前面的节点状态。

二、ZAB 的两种模式

ZAB 可以从两个阶段理解:崩溃恢复和消息广播。崩溃恢复发生在集群启动、Leader 挂掉或网络分区恢复时。系统要选出新 Leader,并确保新 Leader 拥有不会丢失已提交事务的日志历史。只有恢复完成,集群才能安全进入对外写入状态。

消息广播是稳定期的正常写路径。Leader 接收客户端写请求,生成事务 Proposal,分配全局递增的 zxid,广播给 Follower。Follower 持久化后回复 ACK。Leader 收到多数 ACK,就广播 Commit,随后各节点按 zxid 顺序应用事务。

三、zxid 为什么重要

zxid 是 ZAB 理解事务顺序的核心。它通常由 epoch 和 counter 组成。epoch 对应 Leader 纪元,Leader 每次更换都会进入新的 epoch;counter 是该 Leader 任期内递增的事务编号。这样 zxid 既能表示全局顺序,也能区分旧 Leader 和新 Leader 的事务。

当新 Leader 产生时,epoch 会变大。旧 Leader 即使恢复发送旧消息,也会因为 epoch 落后而失效。Follower 也可以根据 zxid 判断自己日志是否落后,需要从 Leader 处同步缺失事务,或者截断未提交事务。

四、ZAB 如何保证已提交事务不丢

ZAB 的提交依赖多数派。某个事务只有被多数节点 ACK 后,Leader 才能提交。Leader 失败后,新 Leader 的选举和同步必须覆盖多数派历史。由于任意两个多数派有交集,已提交事务至少会被新 Leader 选举过程中的某个节点携带。

恢复阶段会处理两个问题:已经提交但部分节点没应用的事务要补齐;旧 Leader 提出但没有提交的事务不能被错误继续提交。通过选择拥有足够新历史的 Leader、同步日志、截断不合法尾部,ZAB 保证所有节点最终沿着同一条事务日志前进。

五、ZooKeeper 的一致性语义

ZooKeeper 的写请求通过 Leader 和 ZAB 多数派提交,因此写入顺序在集群内一致。客户端会话还会看到顺序一致性:同一个客户端发出的请求按顺序处理。Watcher、临时节点、会话超时等机制都依赖这条一致事务日志。

不过 ZooKeeper 的读请求默认可以由连接的 Follower 直接返回,这意味着读可能不是最新的。如果客户端刚向 Leader 写成功,随后连接到落后 Follower 读取,理论上可能读到旧值。需要强读时可以调用 sync,让服务器与 Leader 同步到较新状态后再读。

六、面试追问与工程边界

常见追问是 ZAB 和 Paxos、Raft 的关系。可以说它们都使用多数派和 Leader 思想,都要保证已提交日志不丢。ZAB 更贴近 ZooKeeper 的事务广播场景,强调主备恢复和原子广播;Raft 则以更通用、更易理解的方式描述选举、日志复制和安全性。

另一个追问是 ZooKeeper 为什么适合做协调服务而不是高吞吐数据存储。原因是 ZAB 写入要经过 Leader、多数 ACK 和有序提交,强一致协调很可靠,但写吞吐不会像无主或弱一致系统那样横向扩展。

七、常见误区与追问

这道题不能只背概念,要把「Zab 协议」放回真实分布式系统里解释:参与方是谁、状态怎么流转、失败后怎么恢复,以及它在一致性、性能、可用性之间做了什么取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论Zab 是 ZooKeeper 的崩溃恢复和原子广播协议,Leader 提议事务,Follower 多数派 ACK 后提交不要停在名词解释
流程机制Leader 生成 Proposal 和 zxid -> Follower 写入事务日志并 ACK -> Leader 收到多数 ACK -> Leader 广播 Commit -> Follower 应用事务 -> 故障后选新 Leader 同步日志说明触发方、存储方、确认点和兜底
工程取舍3 节点 ZooKeeper 集群中,写事务至少 Leader 加 1 个 Follower 记录成功才能提交一致性协议用延迟和可用性换确定顺序,不能只背 Paxos/Raft 名词
Zab 协议 面试拆解:
1. Leader 生成 Proposal 和 zxid
2. Follower 写入事务日志并 ACK
3. Leader 收到多数 ACK
4. Leader 广播 Commit
5. Follower 应用事务
6. 故障后选新 Leader 同步日志

记忆钩子:先说明故障模型和多数派,再拆选主、日志复制、提交、恢复和安全性边界;回答时要紧扣「Zab 协议」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:Zab 每个节点都能独立提交写。 写请求由 Leader 定序,提交依赖多数派。
  • 误区:zxid 只是普通递增 ID。 zxid 同时表达 epoch 和事务顺序,是恢复同步的重要依据。
  • 误区:ZooKeeper 读写都必须过 Leader。 写经 Leader,读可从 Follower 读但可能受一致性语义影响。
  • 追问:Zab 两个模式是什么? 崩溃恢复和消息广播。
  • 追问:为什么需要多数 ACK? 保证提交事务存在于多数派,新 Leader 恢复时不会丢失。
  • 追问:Leader 崩溃时怎么恢复? 选出拥有最新历史的节点为 Leader,并同步差异日志。

八、加强记忆

ZAB 可以记成“ZooKeeper 的有序事务广播”。恢复阶段选出安全 Leader 并同步历史;广播阶段 Leader 分配 zxid、发送 Proposal、多数 ACK 后 Commit;zxid 用 epoch 区分 Leader 任期,用 counter 表示事务顺序。已提交事务靠多数派交集不丢,未提交事务在恢复时可能被截断。