工作流程
Multi Paxos对Paxos的核心改进是,增加了“选主”的过程:
提案节点会通过定时轮询(心跳),确定当前网络中的所有节点里是否存在一个主提案节点;一旦没有发现主节点存在,节点就会在心跳超时后使用 Basic Paxos 中定义的准备、批准的两轮网络交互过程,向所有其他节点广播自己希望竞选主节点的请求,希望整个分布式系统对“由我作为主节点”这件事情协商达成一致共识;如果得到了决策节点中多数派的批准,便宣告竞选成功。当选主完成之后,除非主节点失联会发起重新竞选,否则就只有主节点本身才能够提出提案。此时,无论哪个提案节点接收到客户端的操作请求,都会将请求转发给主节点来完成提案,而主节点提案的时候,也就无需再次经过准备过程,因为可以视作是经过选举时的那一次准备之后,后续的提案都是对相同提案ID的一连串的批准过程。我们也可以通俗地理解为:选主过后,就不会再有其他节点与它竞争,相当于是处于无并发的环境当中进行的有序操作,所以此时系统中要对某个值达成一致,只需要进行一次批准的交互即可。具体如下序列所示:
二元组 (id, value) 已经变成了三元组 (id, i, value),这是因为需要给主节点增加一个“任期编号”,这个编号必须是严格单调递增的,以应付主节点陷入网络分区后重新恢复,但另外一部分节点仍然有多数派,且已经完成了重新选主的情况,此时必须以任期编号大的主节点为准。从整体来看,当节点有了选主机制的支持后,就可以进一步简化节点角色,不必区分提案节点、决策节点和记录节点了,可以统称为“节点”,节点只有主(Leader)和从(Follower)的区别。
达成一致
在这个理解的基础上,我们换一个角度来重新思考“分布式系统中如何对某个值达成一致”这个问题,可以把它分为下面三个子问题来考虑:
如何选主,如何把数据复制到各个节点上,如何保证过程是安全的,当这三个问题同时被解决时,就等价于达成共识。
剔除选主的细节,如心跳,超时等,选主的过程就是达成共识的过程,可参见上一篇的内容。
数据复制要保证能正常工作的节点数满足多数派的要求,由于网络故障,可能存在网络分区,当故障恢复后,会通过心跳包找到任期标号更大的节点作为新的主节点,旧的节点会回滚未提交的变更,从而使所有节点达成最终一致。
保证安全,需要先看下Safety和Liveness这两个术语。它们也是由Lamport最先提出的,定义是:
协定性(Safety):所有的坏事都不会发生。
终止性(Liveness):所有的好事都终将发生,但不知道是啥时候。
以选主问题为例,Safety保证了选主的结果一定是有且只有唯一的一个主节点,不可能同时出现两个主节点;而Liveness则要保证选主过程是一定可以在某个时刻能够结束的。
分布式共识算法更多的讲的是理论,理解Paxos对理解许多分布式工具,有一定的好处。