Skip to content

ZAB 协议 ​

ZAB(ZooKeeper Atomic Broadcast,ZooKeeper 原子广播)是 ZooKeeper 的原子广播协议,用于保证 ZooKeeper 集群的一致性。ZAB 类似 Raft,有领导者选举和消息广播两个阶段。

ZAB 的背景 ​

ZooKeeper 是 Apache 的分布式协调服务,用于分布式锁、配置管理、 leader 选举。ZooKeeper 需要保证多个副本的数据一致性,因此设计了 ZAB 协议。

ZAB 的目标是保证所有副本的顺序一致性:所有节点看到相同的事务顺序。

ZAB 的角色 ​

Leader(领导者) ​

Leader 接收客户端请求,将请求广播给 Follower。Leader 是唯一的,系统中最多有一个 Leader。

Leader 的职责:接收客户端请求、将请求广播给 Follower、收集 Follower 的确认、提交已确认的事务。

Follower(跟随者) ​

Follower 响应 Leader 的请求,包括事务请求和心跳请求。Follower 可以处理读请求,但写请求需要转发给 Leader。

Follower 的职责:响应 Leader 的事务请求、响应 Leader 的心跳请求、处理客户端读请求、如果长时间未收到 Leader 心跳,则发起选举。

Observer(观察者) ​

Observer 不参与选举和事务确认,只接收 Leader 的事务广播。Observer 可以扩展读能力,但不影响写性能。

Observer 的职责:接收 Leader 的事务广播、处理客户端读请求、不参与选举和投票。

消息广播 ​

事务提交流程 ​

客户端向 Follower 提交事务请求,Follower 将请求转发给 Leader。

Leader 为事务分配全局递增的 ZXID(ZooKeeper Transaction ID),ZXID 是 64 位,高 32 位是 epoch(纪元),低 32 位是计数器。Leader 将事务广播给 Follower。

Follower 收到事务后,将其添加到事务日志,并向 Leader 发送 ACK。

Leader 收到多数派(N/2 + 1)的 ACK 后,广播 COMMIT 消息,通知 Follower 提交事务。

Follower 收到 COMMIT 消息后,执行事务,更新内存数据库。

消息广播的特性 ​

顺序性:消息按 ZXID 顺序广播,保证所有节点看到相同的事务顺序。

原子性:事务要么被所有节点执行,要么都不执行。只有多数派确认的事务才会被提交。

崩溃恢复 ​

Leader 崩溃 ​

如果 Leader 崩溃,Follower 会发起选举,选出新的 Leader。

新 Leader 必须拥有所有已提交的事务。已提交的事务是指多数派确认的事务,ZXID 最大。

新 Leader 恢复未提交的事务。未提交的事务是指 Leader 已广播但未获得多数派确认的事务,新 Leader 会丢弃这些事务。

Follower 崩溃 ​

Follower 崩溃后恢复,会从 Leader 同步数据。Follower 发送其最后的 ZXID 给 Leader,Leader 发送该 ZXID 之后的所有事务。

Follower 可能落后很多,Leader 可能发送快照(Snapshot)而不是事务。快照是某个时刻的内存数据库状态。

数据一致性 ​

ZAB 保证数据一致性:已提交的事务不会丢失,未提交的事务不会执行。

已提交的事务是指多数派确认的事务,新 Leader 必须拥有这些事务。未提交的事务是指未获得多数派确认的事务,新 Leader 会丢弃这些事务。

Leader 选举 ​

选举触发 ​

Follower 如果长时间(timeout,默认 2 倍 tickTime)未收到 Leader 心跳,则认为 Leader 故障,转为 LOOKING 状态,发起选举。

选举流程 ​

节点广播选举投票(投票包含自己 ZXID),收到其他节点的投票后,比较 ZXID,选择 ZXID 最大的节点作为 Leader。

ZXID 最大的节点拥有最新的事务,选择它可以保证已提交的事务不丢失。

如果节点收到多数票,则成为 Leader,广播 LEADER 消息。其他节点收到 LEADER 消息后,转为 FOLLOWING 状态。

选举的快速恢复 ​

ZAB 的选举可以快速恢复,因为 ZXID 最大的节点直接成为 Leader,不需要额外的数据同步。

ZAB 的选举可以保证数据一致性,因为 ZXID 最大的节点拥有所有已提交的事务。

ZAB vs Raft ​

ZAB 和 Raft 都是 Leader-based 的共识算法,有领导者选举和日志复制两个阶段。

ZAB 的 epoch 类似 Raft 的 Term,ZAB 的 ZXID 类似 Raft 的日志索引和任期号组合。

ZAB 的区别:ZAB 只支持顺序操作(ZooKeeper 是类似文件系统的 API),Raft 支持通用状态机。ZAB 的快照是完整的内存数据库状态,Raft 的快照是状态机的快照。

ZooKeeper 的应用 ​

分布式锁:ZooKeeper 的临时顺序节点可以实现分布式锁。客户端创建临时顺序节点,序号最小的节点获得锁。

Leader 选举:ZooKeeper 的临时节点可以实现 Leader 选举。多个客户端创建临时节点,成功创建的客户端成为 Leader,其他客户端监听该节点。

配置管理:ZooKeeper 的监听机制可以实现配置变更通知。客户端监听配置节点,配置变更时 ZooKeeper 通知客户端。

服务发现:ZooKeeper 的临时节点可以实现服务注册与发现。服务启动时注册临时节点,客户端监听服务列表。

ZAB 的总结 ​

ZAB 是 ZooKeeper 的原子广播协议,保证 ZooKeeper 集群的一致性。ZAB 类似 Raft,有领导者选举和消息广播两个阶段。ZAB 保证顺序一致性、数据一致性,是分布式协调的基础。

理解 ZAB 有助于理解 ZooKeeper 的原理,也有助于理解其他共识算法。