直接回答:ZAB(ZooKeeper Atomic Broadcast)是 ZooKeeper 的原子广播协议,同样基于主备多数派:一个 leader 接收写、按全局递增的 zxid 广播提案,多数派确认(ack)后提交。与 Raft 的差异核心在恢复方向:Raft 新 leader 用自己的日志覆盖 follower;ZAB 恢复阶段让新 leader 与 follower 对齐,历史设计允许 follower 的快照/日志向前“补齐”到 leader——两者都安全,取舍在崩溃恢复的实现路径。
展开解析:协议两阶段拆解:广播阶段——leader 把写请求编成提案按 zxid(高 32 位 epoch、低 32 位计数)顺序发出,收到多数派 ack 后 commit,本地先应用再发 commit 通知;恢复阶段——选新 leader(zxid 最大者优先,保证包含已提交提案),与 follower 做差异同步(DIFF/TRUNC/SNAP 三种对齐方式),对齐完才开放服务。与 Raft 对照记忆:日志方向——Raft 严格 leader 到 follower 单向覆盖,ZAB 的恢复包含 follower 向 leader 汇报后的双向对齐;选举依据——都用“日志最新”限制(zxid vs lastLogTerm/Index);事务顺序——ZAB 保证 FIFO(客户端顺序与全局 zxid 序一致),会话内顺序性比 Raft 的语义更显式;历史成因——ZAB 为“主备数据库加全序广播”设计,Raft 为“可理解性与教学”重新推导。ZooKeeper 使用侧的一致性要点:写线性一致(经 leader),读默认 follower 本地读是陈旧的——sync 命令强制追赶 leader,watch 机制保证“读到的事件流不丢序”。运维关联:ZooKeeper 集群的抖动半数为磁盘延迟(事务日志 fsync),独立 dataLogDir 是标配;observer 角色扩读容量不进多数派,避免投票节点膨胀拖慢写。
追问方向:zxid 的 epoch 变化时机?ZooKeeper 为什么不直接读 leader 保证线性?
(约 490 字)