在这里 有人说:
“即使你每次都从不同的追随者那里读到,你也永远不会 看过版本 4 后,再看版本 3 的数据。”
所以如果我有 3 个节点 Zookeeper 仲裁如下:
zk0 -- leader
zk1
zk2
假设仲裁中有一个值“3”,并且我有一个客户端连接到
zk1
,然后我的客户端发送一个写入请求(将“3”更新为“4”),然后zk0
(领导者)写入该值随后收到zk1
的确认。我的客户可以看到新的(“4”),因为它连接到 zk1
。
现在我的问题是,如果我将客户端从
zk1
切换到zk2
(领导者尚未收到来自zk2
的写入确认,因此zk2
落后于法定人数)我将看到该值为“3”而不是“4”。会破坏顺序一致性吗?
ZooKeeper 使用一种特殊的原子消息传递协议,称为 ZooKeeper Atomic 广播 (ZAB),确保集合中的本地副本(Zookeeper 服务器组)永远不会分歧。
ZAB 协议是原子的,因此该协议保证更新要么成功,要么失败。
在Zookeeper中,每次写入都会经过领导者,领导者会生成一个事务ID(称为zxid)并将其分配给该写入请求。
zxid 是一个长(64 位)整数,分为两部分:
zxid 表示在所有副本上应用写入的顺序。 epoch代表领导力随时间的变化。时期是指给定服务器行使领导权的时期。在一个时期内,领导者广播提案并根据计数器识别每个提案。
如果领导者收到多数人的确认,则认为写入成功。
zxid 用于保持服务器同步并避免您所描述的冲突。
连接到节点时,客户端提交其看到的最新 zxid。如果这比节点看到的最后一个 zxid 新,它将拒绝连接。
因此客户端写入但随后断开连接并重新连接到过时的追随者的情况不会发生(重新连接被节点拒绝)。