山西网站建设鸣蝉,直播软件开发运营需要多少钱,高德开放平台,临海市住房与城乡建设规划局网站ZAB协议
ZAB集群如何从故障中恢复
如果我们想把ZAB集群恢复到正常状态#xff0c;那么新领导者就必须确立自己的领导关系#xff0c;成为唯一有效的领导者#xff0c;然后作为主节点领导各备份节点一起处理读写请求
如何确立领导关系
前面提到#xff0c;选…ZAB协议
ZAB集群如何从故障中恢复
如果我们想把ZAB集群恢复到正常状态那么新领导者就必须确立自己的领导关系成为唯一有效的领导者然后作为主节点领导各备份节点一起处理读写请求
如何确立领导关系
前面提到选举出的领导者是在成员发现阶段确立领导关系的。领导者在当选后会递增自己的任期编号并基于任期编号值的大小来与跟随者协商最终建立领导关系。具体来说跟随者会选择任期编号值最大的节点来作为自己的领导者而被大多数节点认同的领导者将成为真正的领导者。
举个例子。 下面用一个例子来帮助更好地理解。 假设一个ZooKeeper集群由节点A、B、C组成。其中领导者A已经宕机节点C是新选出来的领导者节点B是新的跟随者(为了方便演示假设节点B、C已提交提案的事务标识符的最大值分别是1,10和1,11其中1是任期编号10、11是事务标识符中的计数器值节点A宕机前的任期编号也是1)如图所示。那么节点B、C如何协商建立领导关系呢
首先节点B、C会把自己的ZAB状态设置为成员发现(DISCOVERY)这就表明选举(ELECTION)阶段结束了进入了下一个阶段如图所示。
这里补充一下ZAB协议定义了4种状态来标识节点的运行状态。 1.ELECTION(选举)状态:表明节点在进行领导者选举 2.DISCOVERY(成员发现)状态:表明节点在协商沟通领导者的合法性 3.SYNCHRONIZATION(数据同步)状态:表明集群的各节点以领导者的数据为准修复数据副本的一致性 4.BROADCAST(广播)状态:表明集群各节点在正常处理写请求。 关于这4种状态简单了解即可。强调一点只有当集群大多数节点处于广播状态的时候集群才能提交提案。
接下来节点B会主动向节点C发送包含自己接收到的领导者任期编号的最大值(也就是前领导者A的任期编号1)的FOLLOWINFO消息如图所示。
节点C在接收到来自节点B的信息后会将包含自己的事务标识符的最大值的LEADINFO消息发送给跟随者。需要注意的是领导者进入成员发现阶段后会对任期编号加1即创建新的任期编号然后基于新任期编号创建新的事务标识符(也就是2,0)如图所示。
当接收到领导者的响应后跟随者会判断领导者的任期编号是否最新如果不是就发起新的选举如果是则返回ACKEPOCH消息给领导者。在这里 节点C的任期编号(也就是2)大于节点B接收到的其他领导任期编号(也就是旧领导者A的任期编号1)所以节点B返回确认响应给节点C,并设置ZAB状态为数据同步状态如图所示
最后领导者在接收到来自大多数节点的ACKEPOCH消息时会设置ZAB状态为数据同步。在这里节点C接收到了节点B和节点C自己发送的消息满足大多数节点的要求所以在接收到来自B的消息后C设置ZAB状态为数据同步状态。如图所示
现在ZAB协议在成员发现阶段确立了领导者的领导关系这样领导者就可以行使领导职能了。下一步ZAB协议要解决的就是数据冲突问题以实现各节点数据的一致性那么它是怎么做的呢
如何处理冲突数据
当进入数据同步状态后领导者会根据跟随者的事务标识符的最大值判断以哪种方式处理不一致数据(有DIFF、TRUNC、SNAP3种方式)。 因为节点C已提交提案的事务标识符的最大值(也就是1,11)大于节点B已提交提案的事务标识符的最大值(也就是1,10),所以节点C会用DIFF的方式修复数据副本的不一致。并返回差异数据(也就是事务标识符为1,11的提案)和NEWLEADER消息给节点B,如图所示. 这里强调一点:节点B已提交提案的最大值也是节点B最新提案的最大值。因为在ZooKeeper实现种节点退出跟随者状态时(也就是在进入选举前)所有未提交的提案都会被提交。这是ZooKeeper的设计。
然后节点B修复不一致数据返回NEWLEADER消息的确认响应给领导者(即节点C),如图所示.
接着节点C在接收到来自大多数节点的NEWLEADER消息的确认响应后会将ZAB状态设置为广播状态。在这里节点C接收到节点B和节点C自己的确认响应满足大多数确认的要求。所以在接收到来自节点B的确认响应后节点C会将自己的ZAB状态设置为广播状态并发送UPTODATE消息给所有跟随者通知它们数据同步已经完成了如图所示。
最后当节点B接收到UPTODATE消息时它就直到数据同步已经完成并设置ZAB状态为广播状态如图所示
注意
在ZooKeeper的代码实现中处于提交状态的提案是可能会改变的为什么呢 在ZooKeeper中一个提案进入提交状态的方式有两种:被复制到大多数节点上和被领导者提交或接收到来自领导者的提交消息(leader.COMMIT)而被提交。 在这种状态下提交的提案是不会改变的。 另外在ZooKeeper的设计中节点在退出跟随者状态时(在follower.shutdown()函数中)会将所有本地未提交的提案都提交。需要注意的是此时提交的提案可能并未被复制到大多数节点上而且这种设计会导致ZooKeeper中出现处于提交状态的提案可能会被删除(也就是接收到领导者的TRUNC消息而删除的提案)的情况。 更准确地说在ZooKeeper中被复制到大多数节点上地提案最终会被提交并不会再改变而只在少数节点存在地提案可能会被提交和不再改变也可能会被删除。为了更好地理解举个具体的例子。 如果写请求对应的提案SET X1已经复制到大多数节点上那么它最终会被提交之后也不会再改变。也就是说再没有新的X赋值操作的前提下不管节点怎么崩溃、领导者如何变更你查询到的X的值都为1。 如果写请求对应的提案SET X1未被复制到大多数节点上比如在领导者广播消息过程中领导者崩溃了那么提案SET X1可能会被复制到大多数节点上提交并不再改变也可能会被删除。这个行为是未确定的具体取决于新的领导者是否包含该提案。 另外补充下在ZAB协议选举出了新的领导者后该领导者不能立即处理写请求还需要通过成员发现、数据同步两个阶段进行故障恢复。这是由于ZAB协议的设计决定的不是所有的共识算法都必须这样比如通过Raft算法选举出新的领导者后领导者是可以立即处理写请求的。