《从Paxos到ZooKeeper》一致性协议(二)之Paxos
(一)、拜占庭问题
拜占庭问题即信道不可靠问题,在分布式系统中是不存在的或者说是很容易解决的。
(二)、Paxos要解决的问题
议会通过法令问题:议员通过信使进行消息传递,议员和信使都可能离开议会,在这种情况下,如何保证议会法令正确产生,不会出现冲突。
(三)、Paxos算法详解
paxos要保证内容
paxos要保证以下几点:
paxos算法中有三种参与角色:Proposer(提议者),Acceptor(决策者)和Learner(不提议不参与决策,要获取到最终的提议的)
提案的选定
提案的两条规则
Proposer向每一个Acceptor集合发送提案,当超过半数的Acceptor通过提案,则认为该提案被选定。
P1:一个Acceptor必须批准它接收到的第一个提案
P1引起的问题是,可能会没有提案被选中(每个Acceptor都批准第一个,那么没有一个提案能超半数)。
所以,Acceptor必须能够批准不止一个提案。因此,可能出现多个提案被选定的情况。由此引入P2
P2:如果编号为M0,Value值为Value0的提案被选定了,那么有比编号M0更高的,且被选定的提案,其Value值必须也是V0
P2保证了即使多个提案被选定,但是他们的结果相同(Value相同)。
我们可以通过P2a来满足P2
P2a:如果编号为M0,value值为V0的提案被选定了,那么有比编号M0更高的,且被Acceptor批准的提案,其Value值必须也是V0
因为P1的存在,所以在Acceptor 1没有接收到任何提案的情况下,其他4个Acceptor已经批准了来自Proposer 2的提案[M0, V1],而此时,Proposer 1产生了一个具有其他Value值得,编号更高的提案[M1,V2],并发送给了Acceptor 1。根据P1,就需要Acceptor 1批准该提案,但是这与P2a是矛盾的,于是我们引入P2b
P2b: 如果一个提案[M0, V0]被选定后,那么之后任何Proposer产生的编号更高的提案,其Value值都为V0
对P2b进行强化,得到P2c:
实际上P2c规定的是一种Proposer生成规则,根据这个规则生成提案时满足P2c。
书上要证明的是由P2c可以推到得到P2b。即当提案[M0, V0]被选定后,设比该提案编号大的提案为[Mn,Vn],在P2c的前提下,对于所有的[Mn, Vn],存在Vn=V0。
那么根据生成规则生成提案后,就能满足P2c,从而满足P2b。最终满足P2和P1,从而达到分布式一致。
接下来看看Proposer如何生成提案
Proposer在产生一个编号为Mn的提案时,必须要知道当前某一个将要或已经被半数以上Acceptor批准的编号小于Mn但为最大编号的提案。并且,Proposer会要求所有的Acceptor都不要再批准任何编号小于Mn的提案。由此引出如下的提案生成算法:
此阶段称为prepare请求,当提案确定后,proposer会发起accept请求。
接下来看看Acceptor如何批准提案
Acceptor的算法优化
learner的提案获取
这一块核心思想就是Acceptor会将批准过的提案发给Learner,可以给全部Learner发,也可以只发一部分Learner节省网络,由部分leaner统计出最终选定的提案,并最后通知到全部learner。
通过选主Proposer保证算法的活性
为了避免Paxos陷入无限循环,必须选择一个主Proposer,并规定Proposer才能提出议案,但凡主Proposer提出一个编号更高的提案,该提案最终会被批准。如果Proposer发现当前算法流程已经有一个编号更大的提案被提出或批准,它会丢弃当前这个编号更小的提案,并最终选出一个编号更大提案。