本文目录导读:

Zab协议(ZooKeeper Atomic Broadcast,原子广播协议)是 ZooKeeper 保证数据一致性的核心协议,它专门为 ZooKeeper 设计,用于处理崩溃恢复和原子广播。
Zab协议确保在分布式系统中,所有服务器(节点)对数据的修改顺序达成一致,并且即使在Leader崩溃后,也能保证数据不丢失且状态一致。
核心目标
- 原子性:一个事务要么在所有节点上成功提交,要么都不提交。
- 顺序性:所有事务(写请求)按照全局唯一顺序执行。
- 可靠性:一旦一个事务被提交,即使Leader崩溃,它也不会丢失。
关键角色
Zab协议中有三种角色,与ZooKeeper的集群角色对应:
| 角色 | 说明 |
|---|---|
| Leader | 负责处理所有写请求,生成事务提议(Proposal),并广播给所有Follower。 |
| Follower | 接收Leader的提议,投票,并将结果应用到内存数据库,同时处理读请求。 |
| Observer | 类似Follower,但不参与投票,只同步数据,用于扩展读性能。 |
核心工作流程:两个阶段
Zab协议主要分为两个阶段:
崩溃恢复(Leader Election & Recovery)
目的:当集群启动或Leader宕机时,选出一个新的Leader,并确保所有服务器上的数据恢复到最新、一致的状态。
- 如何选举:ZooKeeper使用基于Paxos-like的选举算法(如Fast Leader Election),选举的依据通常是事务ID(ZXID)。
- 关键概念:
- ZXID:一个64位的数字,高32位代表纪元(Epoch,即Leader的任期),低32位代表该纪元内的事务计数器,ZXID越大,代表数据越新。
- 数据同步:新Leader选出后,会找出集群中拥有最高ZXID的服务器(通常是它自己),并将自己的最新事务日志同步给所有Follower/Observer,如果Follower有未被提交的事务,Leader会确保它们被丢弃或重新提交,保证最终状态一致。
原子广播(Atomic Broadcast)
目的:在正常的运行状态下,确保Leader提出的每一个写请求都能被集群中的所有节点按照相同的顺序提交。
- 流程(类似于两阶段提交):
- 客户端发送写请求:客户端将写请求发送给Leader(或由Follower转发给Leader)。
- Leader生成提议:Leader生成一个全局唯一的ZXID(递增),并将该写操作封装成一个提议。
- 广播提议:Leader将提议广播给所有Follower(通过FIFO的TCP连接)。
- Follower反馈:Follower收到提议后,将其写入本地事务日志(持久化),并返回ACK给Leader。
- Leader提交:Leader收到超过半数(法定人数) 的ACK后,认为该提议已通过,Leader会广播一个COMMIT消息给所有Follower。
- Commit:Leader和所有Follower收到COMMIT消息后,将该事务应用到内存数据库(ZooKeeper的数据模型是内存中的树结构)。
Zab vs. Paxos vs. Raft
Zab协议与Paxos、Raft同属共识算法家族,但有专门的设计:
| 特性 | Zab | Paxos | Raft |
|---|---|---|---|
| 主要用途 | ZooKeeper | 通用分布式共识(学术界) | 通用分布式共识(工业界流行) |
| 核心思想 | 原子广播 + 崩溃恢复 | 多轮投票 + 领导者选举 | 强领导者 + 日志复制 |
| ZXID | 有,区分纪元与序号 | 无直接对应 | 有Term(任期)和Log Index |
| 选主条件 | 数据最新(最高ZXID) | 通常基于编号 | 数据最新(最高Term + Log Index) |
| 消息顺序 | 严格全局有序(FIFO) | 不保证全局有序(需额外处理) | 严格全局有序(FIFO) |
| 是否保证单调读 | 是 | 需额外实现 | 是 |
经典比喻:
- Paxos 像一个讲究“议会讨论”,法律通过前需要大家统一意见。
- Raft 像一个讲究“领导决策”,领导说了算,但领导不行就换。
- Zab 更像 “一个强领导 + 原子广播” ,尤其强调在Leader崩溃后,新Leader必须拥有最新的数据,不能丢失任何已提交的事务。
为什么ZooKeeper选择了Zab而不是Paxos?
- 性能优化:Zab专门为ZooKeeper的读多写少场景设计,它利用FIFO通道保证了消息的全局有序性,避免了Paxos中复杂的消息乱序和冲突处理。
- 实现简化:Zab协议通过ZXID和数据同步机制,优雅地解决了崩溃恢复问题,Paxos的完整实现(如Multi-Paxos)相对复杂。
- 强一致性保证:Zab提供了线性一致性(Linearizability),即一旦写操作完成,后续任何读操作都能看到该写操作的结果,这是通过“读请求由Leader处理”或“Follower缓存的Watch”等机制实现的。
关键特性总结
- 强一致性:所有节点上的数据最终完全一致。
- 顺序性:所有写请求按照全局唯一的ZXID顺序执行。
- 高可用:当Leader崩溃时,自动选举新Leader,服务不会间断。
- 数据持久性:写操作在超过半数节点上持久化后才返回成功。
Zab协议是ZooKeeper的“灵魂”。 它通过崩溃恢复和原子广播两阶段,解决了分布式系统中“谁来当领导”、“数据怎么同步”以及“领导挂了怎么办”这三个核心问题,从而保证了ZooKeeper提供了高可用、强一致性的协调服务。