前言
Paxos有三种角色:Proposer(提议者)、Acceptor(审批者)、Learner(领导者)。一个进程可能充当不止一个角色。
Paxos算法的目标是保证最终有一个提案被选定,当提案选定后,进程最终也能获取到被选定的提案。
提案
:由一个全局唯一编号和Value组成,且编号是全部有序的。
Acceptor集合
:为半数以上Acceptor组合成的集合。 那么任意两个半数以上的Acceptor集合,必定包含至少一个公共Acceptor。
提案的选定
- 一个提案被选定,必须被至少一个Acceptor批准,
- 允许多个提案被选定,但同时必须要保证所有被选定的提案都具有相同的Value值。
如果编号为M0、Value值为V0的提案([M0,Value0])被选定了,
那么所有比编号M0更高的,且被选定的提案,其Value值必须也是V0
- 一个提案被选定,那么所有比编号M0更高的,且被Acceptor批准的提案,其Value值必须要也是V0.
- 一个提案被选定,那么之后任何Proposer产生的编号更高的提案,其Value值为V0。
Proposer生成提案
Proposer产生一个编号为 Mn的提案时,必须要知道当前某一个将要或已经被半数以上Acceptor批准的编号小于Mn但为最大编号(已批准的)的提案。并且,Proposer会要求所有的Acceptor都不要再批准任何编号小于Mn的提案。
- Proposer选择一个新的提案编号Mn,然后想某个Acceptor集合的成员发送请求,要求该集合中的Acceptor做出如下响应。将该过程为编号Mn提案的Prepare(准备)请求。
1.1 想Proposer承若,保证不再批准任何编号小于Mn的提案。
1.2 如果Acceptor已经批准过任何提案,那么就向Proposer反馈当前该Acceptor集合中已经批准的编号小于Mn但为已批准最大编号的那个提案值。 - 如果Proposer收到来自
半数以上
的Acceptor的响应结果,那么它就可以产生编号为Mn、Value值为Vn的提案。
2.1 如果响应中包含提案,那么Vn的值为响应中编号最大提案的Value值
。
2.2 如果响应中不包含任何提案(即半数以上的Acceptor都没有批准过任何提案),那么Vn值就可以由Proposer任意选择
。
确定提案后,Proposer就会将提案发送给某个Acceptor集合,并期望获得它们的批准,
Acceptor批准提案
一个Acceptor可能会受到来自Proposer的两种请求,分别为Prepare请求和Accept请求。
- Prepare请求:Acceptor可以在任何时候响应一个Prepare请求。
- Accept请求:在不违背Accept现有承若的前提下,可以任意响应Accept请求。
提案的获取
Learner获取提案:前提是该提案已被半数以上的Acceptor批准。
方案一
Acceptor批准了一个提案,就将该提案发送给所有的Learner。虽然可以让Learner尽快的获取被选定的提案,但是每个Acceptor需要与所有的Learner进行通信,导致通信次数过多。
方案二
让所有的Acceptor将它们对提案批准的情况,统一发给给一个特定的Learner(主Learner),当主Learner被通知一个已被选定的提案是,它会通知其他的Learner。虽然减少了通信次数,但是导致Learner随时可能出现故障的不稳定因素。
方案三
在方案二的单点问题中,将主Learner范围扩大,即Acceptor可以将批准的提案发送给一个特定的Learner集合,该集合中的每个Learner都可以在一个提案被选定后通知所有其他的Learner。虽然Learner集合中Learner个数越多,可靠性就越好,但同时网络通信的复杂度也越高。
通过选取主Proposer保证算法的活性
保证Paxos算法流程的可持续性,以避免陷入”死循环“
,就必须选择一个主Proposer,并规定只有主Proposer才能提出议案。
这样一来,只要主Proposer和过半的Acceptor能够正常通信,那么主Proposer提出一个编号更好的提案,该提案终会被批准。
如果Proposer发现当前算法流程中已经有一个编号更大的提案被提出或正在接受批准,那么它会丢弃当前这个编号较小的天,并最终能够选出一个编号足够大的提案。
死循环
Proposer P1提出一个编号为M1的提案,并完成阶段一的流程,但与此同时,另外一个Proposer P2提出了一个编号为M2(M2>M1)的提案,同样也完成了阶段一的流程,于是Acceptor已经承若不在批准编号小于M2的提案,异常,当P1进入阶段二时,其发出的Accept请求被Acceptor忽略,于是P1再次进入阶段一并提出编号为M3(M3>M2)的提案,而这又导致P2在阶段二的Accept请求被忽略,以此类推,提案选定过程将陷入死循环。
总结
Paxos算法引入了”过半“理论,通俗将就是少数服从多数的原则。
同时,Paxos算法支持分布式节点角色之间的轮换,这极大的避免了分布式单节点出现的问题。
因此Paxos算法即解决了无限等到问题,也解决了”脑裂“问题。