一、概述
在前面的一篇文章中我们已经对 Zab 协议的整体流程进行了分析,在这篇博文里我们继续对 Zab 协议中的一些细节部分进行分析,进一步加深对于协议的理解。
二、算法整体描述
三、算法细节分析
3.1 变量介绍
这里主要补充一个在前一篇博文中忘记描述的变量 zxid ,这个变量是一个长度为 64 位的事务标识符,其中高 32 位为当前的 Epoch 纪元号,低 32 为 Counter 递增计数器。这里需要注意的是对于高 32 位的纪元号每次产生新 Leader 后都会进行更新,但是对于低 32 位的计数器是一直处于递增的状态的,不存在当高 32 位更新后重置低 32 位的情况。
3.2 细节概述
在开始正式的分析之前我们先大概介绍一下 Zab 协议中 Zab 节点可能处于的三个状态,它们分别是 Election 、 Following 和 Leading,每一个 Zab 节点起始状态都为 Election 状态,即寻找一个可以跟随的 Leader,当其查找到相应的 Leader 后就会转换为 Following 状态,而如果其自己被确定为 Leader,那么它就会转换为 Leading 状态。
而 Zab 协议的基础交付协议又是一种 2PC(two phase commit)的形式,即首先主机创建事务后会按照 FIFO 的顺序对事务进行广播,当 Follower 接收到该事务并成功将其持久化之后会回复对应的 ACK 消息来确认该事务,而当 Leader 接收到超过法定数量的 Follower 对该事务的 ACK 之后就会给这些 Follower 发送 COMMIT 提议来让它们提交该事务,而当 Follower 就收到该 COMMIT 提议后就会提交该事务和该事务之前所有未提交的事务(这里主要是根据 zxid 来判断事务的先后顺序)。
3.3 确立一个新的 Leader(关于 Election 状态)
对于 Zab 算法的细节剖析就先从确立一个新 Leader 的过程讲起,如果你看过我前面那篇 Zab 算法整体描述应该已经大致了解了 Zab 算法的整体流程,但在那篇文章的算法概述一节里我留下了一个坑,也就是下面的这段话。
但是需要注意的是在经过 Phase 1 后只能说该 Zab 节点根据 Leader Oracle 被选择成为了 Leader,但是此时它还没有完全建立起领导关系(LeaderShip),也就是它目前还不具备领导其它的 Zab 节点的能力,只有当它完成了 Phase 2 的同步后才真正建立了对其它 Zab 节点的领导关系,
这里提到了一个 Leadership 领导关系的建立,首先在论文中对于 Leader 的选举存在两种描述,第一种是 Select Leader 即选择一个 Leader,而第二种是 Establish Leader 即确立一个 Leader 。
而正如我们上面所述,当 Zab 算法完成 Phase 1 后仅仅是完成了 Select Leader 的过程,而这个 Select Leader 的过程准确来说又是由我们自己所提供的选举算法完成的(对于这个 Leader ELection 算法 Zab 协议没有进行严格的要求,只要它能够输出一个合适的 Leader 就可以了),而真正确立 Leader 对于 Follower 的领导关系应该是在 Phase 2 的 Establish Leader 之后完成,因此接下来我们就先回顾一下整个的 Leader Election 过程(以下内容源自论文 Zab: High-performance broadcast for primary-backup systems)。
-
当一个 Zab 节点发现 Leader Election 算法输出的 Leader 是它的时候,它会立即进入到 Phase 1 开启新的迭代;
-
在开始新的迭代后它首先会收集超过法定数量 Follower 中最新的 Epoch,然后将其递增后作为 NEWEPOCH 提议发送给刚刚超过法定数量的 Follower ,并从它们返回的 ACK 信息中再次收集最新的 Epoch 和最大的 zxid ;
-
最终当 Leader 从 Follower 返回的 ACK-E(f.a,hf) 信息中获取到具备最新 Epoch 和最大 zxid 的 Follower 的 hf 后它就完成了 Phase 1 ,也就是完成了新 Epoch 的确立;
-
进入到 Phase 2 后该 Leader 会通过发送 NEWLEADER(e,Ie) 提议的方式来提议它自己成为真正的 Leader ,其中 Ie 就是最新 Epoch e 的初始化数据;
-
当 Leader 一旦接收到超过法定数量的 Follower 对 NEWLEADER 的 ACK 确认信息就可以被确立为真正的 Leader 了,同时它会发送 COMMIT 提议给 Follower 让它们提交同步后的新提议;
-
而当 Follower 接收到确立后的新 Leader 的 COMMIT 提议后就会提交它们之前同步过但未提交的所有新提议,至此完成 Phase 2;
对于上述的第三点论文中提到的优化方式即 Follower 不需要将其所有的历史数据 hf 都放在 ACK 中发送给 Leader,而只需要将其最大的 zxid 发送给 Leader 就可以了,因为通过 zxid 就足以让 Leader 知道其是否需要从这个 Follower 中拷贝缺失的事务数据了(如果缺失数据那么后续再进行拷贝就可以了),而第四点中的 Ie 同理并不需要发送全部的初始化数据,只需要发送 Follower 所缺失的初始化数据就可以了(因为在 Phase 1 中我们已经通过 ACK 获取到了每个 Follower 最新的数据信息了,只需将其与初始化数据进行对比后发送缺失数据就可以了)。但其实通过这点我们也能看出来 Zab 协议对 Leader Election 算法是没有什么太多要求的,哪怕 Leader Election 选举出来的 Leader 没有包含所有的数据,它也可以通过从 Follower 中拷贝缺失数据的方式来保证该 Leader 包含了所有 Zab 节点中最新最全的数据。
在上面的第四点中我们提到了 Leader 通过发送 NEWLEADER 提议方式来提议它自己成为 真正的 Leader ,这里为什么要强调这个真正呢,因为如果你仔细观察我们在 Phase 1 时对于该 Leader 的称谓都是 预期的 Leader,也就是说它仅仅是 Leader Election 算法输出的一个 Leader ,目前还不是 Zab 算法中的 Leader。这主要是因为当它被 Leader Election 算法选举出来就意味着它已经是 Leader Election 算法认可的 Leader,只不过暂时 Zab 算法还不能确定其数据的 最新性和最全性 ,所以暂时不能认可这个 Leader 。因此在 Phase 1 过程中它先进行了新 Epoch 的提议(NEWEPOCH),算是提议开始一个新的纪元,而当它完成了 Phase 1 后它就完成了自己数据的更新和同步,并可以理解为半只脚已经踏入了 Zab Leader 的行列。
Definition V.1. (Established leader) A leader le is established for epoch e if the NEWLEADER(e,Ie) proposal of e is accepted by a quorum Q of followers.
DefinitionV.2. (Establishedepoch) An epoch e isestablished if there is an established leader for e.
最后我们再根据论文中对 已确立 Epoch 和 已确立 Leader 的定义来做一个总结,首先对于一个 Leader l 当其在 Phase 2 发送的 NEWLEADER 提议被超过法定数量的 Follower 确认即可以认为它是一个真正已被确立的 Leader ,而对于一个 Epoch e 只有当存在一个已确立的 Leader 且其对应的 Epoch 为 e 的时候才能认为这个 Epoch e 已经被确立。
四、参考文献
- Zab: High-performance broadcast for primary-backup systems