ZAB 协议详解
ZAB 协议详解
Section titled “ZAB 协议详解”ZAB 协议概述
Section titled “ZAB 协议概述”什么是 ZAB?
Section titled “什么是 ZAB?”ZAB 是 ZooKeeper Atomic Broadcast 协议的简称,是 ZooKeeper 用来实现分布式一致性的核心算法。
ZAB 协议的核心目标:1. 消息广播:保证事务的原子性2. 崩溃恢复:Leader 故障时重新选主3. 数据同步:新 Leader 与 Follower 数据一致ZAB 与 Paxos 的区别
Section titled “ZAB 与 Paxos 的区别”| 特性 | ZAB | Paxos |
|---|---|---|
| 角色 | Leader + Follower | Proposer + Acceptor |
| 场景 | 主备复制 | 分布式共识 |
| 领导人 | 强领导 | 轮流提议 |
| 优化 | 支持崩溃恢复 | 理论性强 |
消息广播(Leader 工作)
Section titled “消息广播(Leader 工作)”┌─────────────────────────────────────────────────────────────┐│ 消息广播流程 │├─────────────────────────────────────────────────────────────┤│ ││ Client Leader ││ │ │ ││ │ 1. 发送写请求 │ ││ │ ─────────────────────────>│ ││ │ │ ││ │ │ 2. 转换为事务 Proposal ││ │ │ ──────────┐ ││ │ │ │ ││ │ │ 3. 广播给所有 Follower ││ │ │ ─────────┬──────────────┐││ │ │ │ │││ │ │ ▼ │││ │ │ Follower1 ◄─────────────┤││ │ │ Follower2 ◄─────────────┤││ │ │ ││ │ │ 4. 收到半数以上 ACK ││ │ │ ◄────────┬──────────────┤││ │ │ │ │││ │ │ 5. 提交事务 ││ │ │ ──────────┐ ││ │ │ │ ││ │ 6. 返回成功 │ ▼ ││ │ <─────────────────────────│ Follower1 ◄────────────┘││ │ │ Follower2 ◄────────────┘││ │└─────────────────────────────────────────────────────────────┘- Leader 发起提案:将客户端请求转换为事务 Proposal
- 广播给 Follower:Leader 将 Proposal 发送给所有 Follower
- 收集 ACK:Follower 收到 Proposal 后写入本地日志,返回 ACK
- 半数以上提交:Leader 收到半数以上 ACK 后,提交事务
- 同步给 Follower:Leader 通知 Follower 提交事务
2PC 变种
Section titled “2PC 变种”ZAB 的消息广播本质上是 2PC(两阶段提交) 的变种:
第一阶段(准备): Leader 发送 Proposal → Follower 写入日志 → 返回 ACK
第二阶段(提交): Leader 收到半数 ACK → 发送 COMMIT → 提交事务崩溃恢复(Leader 故障)
Section titled “崩溃恢复(Leader 故障)”- Leader 宕机
- 网络分区导致 Leader 与半数 Follower 失联
- Leader 失去法定票数
┌─────────────────────────────────────────────────────────────┐│ 崩溃恢复流程 │├─────────────────────────────────────────────────────────────┤│ ││ 1. 新的 Follower 发现 Leader 不可用 ││ │ ││ ▼ ││ 2. 进入 Leader 选举状态 ││ │ ││ ▼ ││ 3. 每个节点投票给自己,推举自己为 Leader ││ │ ││ ▼ ││ 4. 互相通信,交换投票 ││ │ ││ ▼ ││ 5. 选出新的 Leader(获得半数以上投票) ││ │ ││ ▼ ││ 6. 新的 Leader 与 Follower 同步数据 ││ │ ││ ▼ ││ 7. 开始处理客户端请求 ││ │└─────────────────────────────────────────────────────────────┘Leader 选举机制
Section titled “Leader 选举机制”ZooKeeper 使用 Fast Leader Election(FLE) 算法:
// 投票数据结构class Vote { long id; // 投票的 Server ID long zxid; // 最大的事务 ID long electionEpoch; // 选举轮次 long state; // 状态}选举原则(按优先级):1. electionEpoch 越大越新(先比较选举轮次)2. zxid 越大数据越新(再比较事务 ID)3. id 越大权重越高(最后比较 Server ID)时间线:─────────────────────────────────────────────────────────────►
T1: Leader 宕机 │T2: Follower1 检测到超时,进入 LOOKING 状态 │ 发送投票 (zxid=100, sid=1) │T3: Follower2 检测到超时,进入 LOOKING 状态 │ 发送投票 (zxid=100, sid=2) │T4: 互相交换投票 │ Follower1 收到 (zxid=100, sid=2) │ → 更新自己的投票为 (zxid=100, sid=2) │ Follower2 收到 (zxid=100, sid=1) │ → 保持投票 (zxid=100, sid=2) │T5: Follower2 获得半数投票,成为 Leader │ 开始发送心跳 │T6: Follower1 收到 Leader 心跳,确认 Follower 角色数据同步机制
Section titled “数据同步机制”| 类型 | 场景 | 说明 |
|---|---|---|
| DIFF | 数据差异小 | 发送差异数据 |
| SNAP | 数据差异大 | 发送完整快照 |
| TRUNC | 多余数据 | 截断多余数据 |
Leader: 1. 计算 Follower 的 zxid 2. 如果差异小 → 发送 DIFF 3. 如果差异大 → 发送 SNAP 4. 如果有多余 → 发送 TRUNC
Follower: 1. 接收同步数据 2. 写入本地日志 3. 更新内存数据 4. 返回 ACKZAB 核心概念
Section titled “ZAB 核心概念”ZXID(事务 ID)
Section titled “ZXID(事务 ID)”ZXID = 高 32 位(epoch)+ 低 32 位(counter)
epoch:选举轮次,每选举一次递增counter:事务计数器,每提交一次递增
例如:0x0000000100000001 → epoch = 1 → counter = 1ZooKeeper Server 状态:┌─────────┐│ LOOKING │ 选举中└────┬────┘ │ ├──> ┌─────────┐ 选举成功 ┌─────────┐ │ │ LEADING │ ─────────► │FOLLOWING│ │ └─────────┘ └─────────┘ │ └──> ┌─────────┐ 选举失败 ┌─────────┐ │ LEADING │ ◄───────── │FOLLOWING│ └─────────┘ └─────────┘面试高频问题
Section titled “面试高频问题”Q1: ZAB 协议的核心是什么?
Section titled “Q1: ZAB 协议的核心是什么?”参考答案:
- 消息广播:Leader 将事务广播给 Follower,半数以上 ACK 后提交
- 崩溃恢复:Leader 故障后重新选主,数据同步
- 数据同步:新 Leader 与 Follower 保持数据一致
Q2: Leader 选举的规则是什么?
Section titled “Q2: Leader 选举的规则是什么?”参考答案:
- 先比较 electionEpoch(选举轮次),越大越新
- 再比较 zxid(事务 ID),越大数据越新
- 最后比较 sid(服务器 ID),越大权重越高
Q3: 如何保证数据一致性?
Section titled “Q3: 如何保证数据一致性?”参考答案:
- 所有写请求由 Leader 处理
- 写请求转换为事务,通过 2PC 广播
- 半数以上 Follower 确认后提交
- Leader 故障时,通过选举恢复一致性