背景
ZooKeeper支持客户端读取和更新具有高可用性的键值对。通过将数据复制到多个节点并让客户端从任何节点读取来实现高可用性。对Zookeeper的设计至关重要的是每个状态变化相对于以前的状态是增量的观察,所以对状态变化的顺序有隐含的依赖性。Zookeeper Atomic Broadcast(ZAB)是驱动ZooKeeper复制订单保证的协议。它还处理选举领导和恢复失败的领导和节点。这篇文章是关于ZAB的。
定义
领导者和追随者 - 在ZooKeeper群集中,其中一个节点具有领导角色,其余的则具有追随者角色。领导者负责接受来自客户端的所有进入状态更改,并将其复制到自己和跟随者。读请求在所有跟随者和领导者之间进行负载平衡。
交易 - 领导传播给其追随者的客户状态更改。
'e' - 领导者的时代。时代是一个领导者在他开始领导时产生的整数,应该大于以前领导人的时代。
'c' - 由领导者生成的序列号,从0开始并增加。它与历元一起使用以对传入的客户端状态更改进行排序。
“史前” - 追随者的历史排队。用于按照到达的顺序提交进入的交易。
未完成的交易 - F.History中具有小于当前COMMIT序列号的序列号的事务集。
ZAB要求
复制保证
可靠的交付 -如果事务M由一个服务器提交,则最终将由所有服务器执行。
总订单 -如果事务A在一个服务器之前在事务B之前提交,则A将由所有服务器在B之前提交。如果A和B是提交消息,则在B或B将在A之前提交时,A将被提交。
因果订单 -如果在B的发件人提交交易A之后发送交易B,则必须在B之前订购A。如果发送方在发送B之后发送C,则C必须在B之后订购。
只要大多数(法定人数)的节点上升,就会复制事务。
当节点发生故障并且稍后重新启动时 - 它应该赶上在关闭时被复制的事务。
ZAB实施
客户端从任何ZooKeeper节点读取。
客户端向任何ZooKeeper节点写入状态更改,并且此状态更改将转发到前导节点。
ZooKeeper使用两阶段提交协议的变体将事务复制到关注者。当领导者从客户端收到更改更新时,会使用续集号c和领导者的纪元e(见定义)生成交易,并将交易发送给所有关注者。追随者将事务添加到其历史队列,并向领导者发送ACK。当领导者从法定人数收到确认信息时,会发送该交易的法定人数COMMIT。接受COMMIT的跟随者将提交此事务,除非c高于其历史队列中的任何序列号。在提交之前,将等待收到COMMIT的所有早期交易(未偿还交易)。
参考文献[4]
在领导崩溃时,节点执行恢复协议,以便在恢复常规操作之前达成共同的一致状态,并建立新的领导者来广播状态更改。
为了执行领导角色,节点必须具有一定数量的节点的支持。由于节点可能会崩溃和恢复,因此可能会有一段时间的多个领导者,实际上相同的节点可能多次执行节点角色。
节点的生命周期:每个节点一次执行该协议的一次迭代,并且在任何时间,进程可以通过进行到阶段0来删除当前迭代并开始一个新的迭代。
第0期 - 未来的领导人选举
阶段1 -发现
阶段2 - 同步
阶段3 - 广播
第1和第2阶段对于使集合处于相互一致的状态,特别是在从碰撞中恢复时尤其重要。
第一阶段 - 发现
在这个阶段,追随者与潜在的领导者进行沟通,以便领导者收集关于其追随者接受的最近交易的信息。这个阶段的目的是发现法定人数中接受交易的最新序列,并建立一个新的时期,以便以前的领导人不能提交新的提案。因为追随者的法定人数已经被前任领导人所接受了所有的改变 - 那么它承诺,目前法定人数中的至少一个追随者在其历史中排队了前任领导人接受的所有改变,这意味着新的领导人将把他们当作好。第1阶段精确算法可用。
阶段2 - 同步
同步阶段总结了协议的恢复部分,使用发现阶段中领导者更新的历史记录同步集群中的副本。领导人与追随者沟通,提出历史上的交易。如果自己的历史落后于领导者的历史,追随者就承认这些建议。当领导人从法定人数中得到确认时,会向他们发出提交信息。在这一点上,据说领导人已经建立起来了,而不是再有前途了。第2阶段精确算法可用。
阶段3 - 广播
如果没有发生崩溃,对等体将无限期地停留在此阶段,一旦ZooKeeper客户端发出写请求,就执行广播事务。第3阶段精确算法可用。
为了检测故障,Zab在追随者及其领导者之间采取周期性的心跳信息。如果领导者在给定的超时期间没有收到来自法定人数的心跳,则放弃其领导,并转向州选和阶段0.如果在超时期间没有从其领导层收到心跳,追随者也将参加领导选举阶段。