ZAB 和 Raft 都是「leader + 多数派」的协议,有什么区别?这篇不比较论文,而是各起一个真实集群:ZooKeeper 3 节点和 etcd 3 节点,测读语义和 leader 故障后的写中断,看实际表现的差异。
不调用 sync:读到旧值 0 / 3000 次;每次读之前先 sync():读到旧值 0 / 3000 次
ZooKeeper 文档说 follower 上的读可能落后于最新写(顺序一致而不是线性一致),sync() 用来补救。我在单机多进程环境下没能复现旧读,所以这里只能报告「没观察到」。
线性一致读(默认):读到旧值 0 / 3000 次;serializable 读(follower 本地):读到旧值 303 / 3000 次
etcd 通过 JSON HTTP 网关访问(serializable: true 选择本地读)。
第 1 次:写不可用 2030 ms;raftTerm 2 → 3 第 2 次:写不可用 2039 ms;raftTerm 3 → 4 第 3 次:写不可用 1784 ms;raftTerm 4 → 5 第 4 次:写不可用 2037 ms;raftTerm 5 → 6 第 5 次:写不可用 1024 ms;raftTerm 6 → 7 etcd 写不可用中位 2030 ms(最小 1024 / 最大 2039);对照 ZooKeeper 第 36 篇的中位约 445 ms
两个系统的默认超时不同(etcd 选举超时 1000 ms、心跳 100 ms;ZooKeeper tickTime 2000 ms),调小之后差距会变。更完整的 etcd 对比见第 108 篇。