美文网首页
聊聊ZAB(三)

聊聊ZAB(三)

作者: lucasgao | 来源:发表于2021-03-22 00:03 被阅读0次

    协议(实现)

    ZAB协议包含2种模式:恢复(recovery)和广播(boradcast)。

    当服务刚启动或者经历leader崩溃的时候,ZAB会切换到 recovery模式。当一个leader选出并且与大多数候选人同步之后,Zab切换到广播模式。

    一旦leader拥有了大多数follower,它就可以广播消息了。 ZAB 广播的leader和相应写请求的leader是一个,这样就减少了不必要的网络传输。(额,我觉得大家都这样认为吧~~~)

    By using the leader that emerges from the recovery mode as both the leader to process write requests and to coordinte the broadcast protocol, we eliminate the network latency of forwarding messages to broadcast from the write request leader to the broadcast protocol leader.

    一旦leader与大多数follower同步之后,他就开始广播消息。 这时候如果有一个新服务加入,那么这个新服务要从 recovery模式开始,发现leader并进行同步。

    只要有大多数服务可用,那么这个服务就是可用的。(这个大家应该也都知道吧)

    广播

    Zab的广播协议类似于二阶段提交:leader发起请求,收集投票,进行提交。但是在ZAB中我们进行了简化,因为不会产生中断,follower要不听从leader,或者不认同leader。 因为我们也没必要像二阶段提交那样等待所有人答复,一旦大多数知晓,那么就提交。

    Zab的广播协议利用 FIFO通道来确保消息发送和接收都有序。

    当发起提案的时候,leader会给每个消息一个id: zxid。Zab是全局有序的协议,所以交付的消息也按照zxid进行排序。通过把消息放到FIFO队列中。当follower收到消息的时候,会进行落盘,并发送ACK。当leader收到大多数的ack之后,进行commit操作。

    恢复

    这个简单的广播可以工作的很少,只要leader或者与follower断连。为了保证可用性,recovery模式 需要选出一个新的leader。对于leader选举,我们应该采用一个高效的算法以保证可用性。这个选举算法要求不仅仅leader认为自己是leader,也要有大多数人的同意。

    在恢复模式下,可能还有些提案可能正在交付,这就又可能造成混乱。为了保证无论何时leader奔溃,该协议都可以正常工作。我们需要保证:

    • 不能忽略任何一个已经交付的消息。never forget delivered messages
    • 不能保留任何一个已经跳过的消息。need to left go of messages that are skipped.

    在一个服务上已经交付的消息,应该在所有的服务上都交付。但是如果一个服务在收到commit请求之前crash,就会导致丢失提交。如下图,因为leader已经提交了该提案,那么所有的服务都应该提交,以保证客户端的一致性视图。

    image.png

    相反,如果一个跳过忽略的消息都不应该保留。同样这个情况也很容易出现,如果Leader生成了一个提案然后在任何人看到之前就出现了一些故障。比如下图 ,没有其他服务器看到编号为3的提案,所以在图4中,当服务器1重新上线并重新集成到系统中时,它需要保证把编号3的提案丢弃。如果服务器1成为新的Leader,并在消息100000001和100000002被提交后提交消息3,这就违反了我们的顺序保证。

    image.png

    确保记住所有已经交付的消息只需要对leader选举做一个简单调整。我们保证选举过程中leader拥有最高的提案编号。这样新选择的leader就有所有已经提交的消息了。我们选取的leader是提案最多的leader,那么新的leader只需要保证所有本地已经提交的消息被大多数follower接收了即可。 这样有个点,就是我们新的leader不需要去拉取其他消息,因为我们新的leader拥有最全的消息。

    无论是leader还是follower在该协议下都可以正常运行。leader保证他的跟随者接收所有消息并 告知他们所有已经commit的。 并且leader通过把follower没有收到的 提案放到队列中,并把这些提案的commit也放到队列里。当新的follower跟上脚步发时候,leader就把他加入广播和ack列表。

    忽略(跳过)那些没有被提交的消息在zab协议中也特别简单。在我们的实现中,zxid是一个64位的数字,其中低32位是一个简单的计数器,每次提案递增。高32位代表任期/轮次(epoch)。每次leader选取,任期都会递增,并重置低32位的计数器。这种操作我们可以把非leader的消息给忽略掉,因为其小于新的提案。并且当leader重连的时候,我们额可以进行check去掉去应该忽略的提案消息。

    相关文章

      网友评论

          本文标题:聊聊ZAB(三)

          本文链接:https://www.haomeiwen.com/subject/ptpacltx.html