Paxos算法(不考虑拜占庭)

Posted 尚书左仆射

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Paxos算法(不考虑拜占庭)相关的知识,希望对你有一定的参考价值。

前置说明:

不论在哪个阶段,客户端在没有成功执行完命令时,“再次尝试”都是进入阶段1而非初始化阶段。

逻辑伪码如下:

---------------------------------------------------------------------------------------------------------------------------------

客户端(提案者)                                              服务器(接收者)

初始化---------------------------------------------------------------------------

c       #等待执行的命令                                      T_max = 0 #当前已发布的最大票号

t = 0 #当前尝试的票号

                                                                          C = _ #当前存储的命令

                                                                          T_store = 0 #用来存储命令C的票

 

阶段1 ---------------------------------------------------------------------------

1. t = t + 1

2. 向所有服务器发消息,请求得到

编号为t的票

                                                                         3. if t > T_max then

                                                                         4.     T_max = t

                                                                         5.   回复:ok(T_store, C)

                                                                         6. end

阶段2 ---------------------------------------------------------------------------

7. if 过半数服务器回复ok then

8.    选择T_store值最大的(T_store, C)

9.    if T_store > 0 then

10.      c = C

11.   end if

12.   向这些回复了ok的服务器发送消息:

      propose(t, c)

13. end if

                                                                         14.  if t == T_max then

                                                                         15.      C = c

                                                                         16.      T_store = t

                                                                         17.      回复:success

                                                                         18.  end if

阶段3 ---------------------------------------------------------------------------

19. if 过半数服务器回复success then

20.    向每个服务器发送消息:execute(c)

21. end if

 ---------------------------------------------------------------------------------------------------------------------------------

由上逻辑可知,申请的票号递增,只要申请成功一张票,则该票号唯一。这主要通过:

3. if t > T_max then

7. if 过半数服务器回复ok then

这两个判断来保证。

        不可能有两个相同的编号同时获得超过半数的ok回复,所以申请成功的票号一定是唯一的,且后续申请成功的票号是一直增加的。

        如果有超过半数的服务器存储了某个提案,则称该提案被选中;此后所有客户端的提案将与该提案相同。

        有被选中的提案,则说明在某个时刻存在(T_store, C)存储在过半的服务器中,且此时在这些服务器中,满足T_store== T_max(阶段2,服务器逻辑);那么当再次有一个票号申请成功时,此时的票号t’必然大于前面的T_max(因为已经有超过一半的服务器保存T_max编号了,小于该编号的票号不可能在阶段1的判断中获取超过半数的ok回复)。由阶段2客户端判断 T_store > 0 的逻辑分支可知,最后t’提案的内容和当前已经被选中的内容是一致的。

        为什么能保证这一点呢?

        因为T_store是在提案被接受的时候设置的(阶段2服务器逻辑),而且此时T_store== T_max将成立。已经有过半的服务器,当前票号的最大值是T_store了。其他服务器保存的最大票号可能大于这个值,也可能小于这个值,但是不论是那种情况,他们的数量加起来都是小于半数的,也就是说不可能有获得客户端提案的机会(客户端提案时,只会向回复了ok的服务器发送提案,且回复ok的服务器数量要超过半数)。小于该值的服务器虽然能更早的满足3. if t > T_max then条件,然而回复ok的数量不足;而大于该值的服务器甚至没有机会回复ok,客户端已经向其他服务器发出提案了,因为有过半的票号小于他们的服务器会回复ok,此时已经满足提案条件了。所以最后通过8.选择T_store值最大的(T_store, C)选出来的提案依然是原来选中的提案。

此外也可以用反证法:

        假设存在一个提案t_提案t已经选中的情况下接着被选中,且他的提案内容c_不同于之前被选中的提案内容c。则,由8.选择T_store值最大的(T_store, C)的逻辑可知,有必然存在一个票号t’; t’ > t,且c’ !=c; 因为被选中的提案t_是之后选中的,所以有t_ > t’; 不能满足假设(永远需要一个t’,而这个t’是不存在的)。

        这样就可以保证,只要服务器还能正常提供服务,那么最后执行的都是同一个提案内容。

以上是关于Paxos算法(不考虑拜占庭)的主要内容,如果未能解决你的问题,请参考以下文章

知识库 | 共识机制演绎:paxos的拜占庭化

如何完美使用Paxos算法,服务生产线上的大规模集群?

转载如何完美使用Paxos算法,服务生产线上的大规模集群?

分布式核心技术

初探一致性协议 Paxos 算法

paxos算法