前言
上篇文章讲了Basic Paxos juejin.cn/post/723509…
但是,Basic Paxos 只能就单个值达成共识,一旦遇到为一系列值实现共识得时候,就不管用了,因此提出Paxos算法得作者兰伯特提出了Multi-Paxos算法,因此进行改进。
在这里可以补充下,Multi-Paxos只是一种思想,而不是算法,他是基于Multi-Paxos思想,通过多个Basic Paxos实例去实现一系列值的共识算法(Raft,ZAB等算法就是它的实现)
Basic paxos的痛点
Basic Paxos决策的过程分为两阶段,准备(Prepare)和提交(Accept),需要多次RPC的交互,耗性能是其中一方面,除此以外,还有引发活锁的可能,导致正确值无法正常写入。
下面讲下什么是活锁:
如果两个提案节点交替使用更大的提案 ID 使得准备阶段成功,但是批准阶段失败的话,这个过程理论上可以无限持续下去,形成活锁(Live Lock)
图解释:
-
横轴是时间,S1,S2,S3接受者在准备阶段中收到了提议者A的3.1编号的3个提案并通过,此时还没进入编号3.1提交阶段。
-
提议者B在准备阶段中又向S3,S4,S5提交了3.5的编号,因为对于S3接受者来说,3.5的提案编号大于3.1的提案编号,故S3接受了3.5的提案。
-
提议者A因为得到了S1,S2,S3的提案通过请求,于是提议者A对3.1编号提案的值X,进行了提交,也就是进行了接收阶段,S1,S2接受者全票通过,但是S3已经接受了3.5的提案,所以拒绝了提议者A的3.1提交。因为需要至少3个节点写入值才算成功,故提议者A的值X写入集群失败。
-
这时候A毫不气馁,生成了编号4.1的提案,并向S1,S2,S3接受者重新发起准备,因为这时候,S1,S2,S3中最大的提案值是3.5,所以通过了提议者A的4.1编号在准备阶段的提案。
-
好戏开场了,提议者B开始向S3,S4,S5提交3.5提案对应的值Y,但是该接受阶段,被S3拒绝了,因为在S3中,通过的最大提案编号是刚刚提议者A提交的4.1, 所以拒绝了提议者B,3.5提案值Y的提交。
-
B也毫不气馁,生成了5.5的提案,并向并向S1,S2,S3接受者重新发起准备,因为这时候,S1,S2,S3中最大的提案值是A提交的4.1,所以通过了提议者B的5.5编号在准备阶段的提案。
- 好戏开场了,提议者A开始向S1,S2,S3提交4.1提案对应的值Z,但是该接受阶段,被S3拒绝了,因为在S3中,通过的最大提案编号是刚刚提议者B提交的5.5, 所以拒绝了提议者A,4.1提案值Z的提交。
- 周而复始,导致值永远无法提交,这也就所谓之活锁。
为了解决以上活锁 & RPC多次交互的问题,Multi Paxos因此提出了领导者和优化了Basic Paxos的方案去优化。
领导者的引入
引入领导者,领导者节点作为唯一的提议者,不存在多个提议者同时提交提案的情况,也就不存在提案冲突的情况了。
优化Basic Paxos执行
省掉准备阶段,直接进入接受阶段。引入了领导者之后,不存在多个提议者,只有领导者这么一个提议者,并且由它说了算,所以也不存在提案冲突,并且直接就进入了接受阶段,省掉了准备阶段,很大程度上减少了往返的消息数,提高性能,降低了延迟。
Chubby中Multi Paxos的实现
Chubby 为了实现强一致性,读写都是在主节点上执行,只要写入成功,所有客户端读到的值都是一样的。
其中写和读的请求流程如下: