Paxos Made Simple 论文解读

最近在看zookeeper相关学习资料,了解到了拜占庭将军问题和Paxos算法都是Leslie Lamport 老爷子提出来的,这两个问题都构造了一个现实场景,让人印象深刻。

接下来开始解读Paxos一致性协议算法。
论文原文

Section 1 一致性问题

对于一致性算法的要求如下:

  • 只有被提议的值才有可能被选中
  • 只有一个值能被选中
  • 直到提议的值被选中后,进程才能获悉到被选中的值

关于活性liveness,这里简单说明了一下:保证一些提议的值最终会被选中,并且这个选中的结果能够被其他进程所获悉。

在该算法中,有三种角色:proposers, acceptors, 和 learners. 在实现中,一个进程可能对应多个角色。

在进程通信中,这里做了两点假设:1. 异步 2. 非拜占庭

  • 每个角色的处理速度不一致,有可能会失败或者重启。由于有可能会在提议值被选中后出现失败的情况,故有一些必要的信息需要进行保存,使得重启后能够恢复。
  • 消息在通信过程中花的时间不一样,有可能会丢失或者重复发送,但是不会被污染(拜占庭将军问题中的背叛情况)

Section 2 选择一个值

最简单的实现方式就是选择一个接收者acceptor,其他提议者proposer发送提议proposal, acceptor选择最先接收到的proposal作为选定的结果。

当然,这种简单的方式存在单点问题,一旦接收者出现失效就无法继续。

所以,我们试着使用另外一种方式:使用多个接收者acceptors,提议者proposer发送提议值proposed value 到一个接收者集合 set of acceptors。 一旦有足够多的接收者批准了提议值,那么该提议值被选中。这里提到一个概念足够多,原文解释了一下,意思就是要保证两个足够多的接收者集合必然存在交集,这也是后面要使用的条件之一。

要求最后能够有提议值被选中,即使只有一个提议值被一个提议者提出。这就意味着:

P1: 一个接收者必须批准它所收到的第一个提议值

这里原文提出了一个问题,在差不多同一时刻可能会有多个提议值被提出,这时会导致接收者批准了不同的提议值,而最终没有一个提议值能占大多数。即使只有两个提议值被提出,也会出现各自占一半的情况(基数个接收者会因为有一个失效而出现投票平局的情况)

鉴于上述情况,为了即满足P1又满足提议值被大多数接收者所批准,那么就必须让接收者可以批准多个提议值。为了跟踪每一个提议被批准的情况,我们通过给每一个提议定义一个唯一的全局有序ID,那么每个提议都可以表示为(ID, Value)对。系统最终要达到的一致性指的是对value达成一致,故我们允许有多个提议Proposal被选中,但是这些提议必须拥有同样的提议值(ID可以不同,代表不同提议者或者不同时间提出来的)。这时我们可以直观的得到一个保证一致性的要求:

P2: 如果一个提议值为v的提议被选中,那么任何更大ID号且被选中的提议也必须拥有同样的提议值v

由于提议是全局有序的,要求P2就保证了所有被选中的提议拥有同样的提议值。

又因为选中的提议是从批准的提议里面选择的,故P2的一个更强版本如下:

P2a:如果一个提议值为v的提议被选中,那么任何更大ID号且被批准的提议也必须拥有同样的提议值v

我们依然保持着P1来保证最终有提议被选中。由于通信过程的异步情况,即使一个提议值为v的提议已经被选中了,可能还存在一个接收者c一直没有批准任何提议。如果此时它接收到了一个更大ID号的提议,且该提议与选中的提议拥有不同提议值。由于条件P1,此时接收者c需要批准该提议,但是这样就会违背P2a。为了保证P1和P2a兼容,我们需要满足一个更强的版本P2b

P2b:如果一个提议值为v的提议被选中,那么ID号更大的提议在提出时拥有同样的提议值v

很显然,这个更强版本的P2b满足的话,P2a和P2自然就满足了。

接下来我们来看怎么来保证P2b。我们假定(m, v)的提议被选定,那么需要证明提议序号为n > m拥有提议值v。为了让证明简单一点,我们使用数学归纳法。假定序号m…(n-1)的提议都拥有提议值v。由于m提议被选中,故必然存在一个大多数接收者集合C,C里面的接收者至少批准m…(n-1)中的提议。接下来我们来构造提议:

P2c:对于任何一个提议(n, v),都必然存在这么一个大多数接收者集合S,保证以下任意一个条件成立。(a) S内没有任何一个接收者批准过序号比该提议小的提议 (b) v等于S内所有接收者的所有被批准的提议中序号最大且小于n的提议的提议值。

通过这种构造方式,只要我们能够保证P2c,那么P2b的条件就满足了。

为了保证P2c,我们在构造提议的时候,需要获取序号小于该提议的已被批准或者将被批准的提议序号以及对应的提议值(由于存在异步情况,有些序号较小的提议可能在我们构造新提议时还未被批准)。获取已批准的提议很简单,但是要预测哪些提议将被批准很困难,所以在这里构造了一个巧妙的方式:在构造提议的时候要求接收者作出一个承诺,不再批准序号小于n的提议。所以整个提议的流程如下:

  1. 选择一个新的提议序号n,发送给一个足够大的接收者集,要求以下答复:

    1. 承诺不再批准序号小于n的提议
    2. 如果批准过序号小于n的提议,返回已批准过的提议中最大序号的提议
  2. 如果在阶段1中,获取到了大多数的相应,那么就可以生成该序号的提议,且提议值为返回响应中序号最大的提议的提议值,如果所有的响应都没有批准过小于n的提议,那么就可以任意选择提议值v

1阶段称为准备阶段,发出的请求称为准备请求;创建完提议后,该提议者把提议发给接收者集,希望接收者批准该提议, 称为批准请求。

上述是从提议者的角度描述该提议构造算法,那么对于接收者呢?它会收到两种不同的请求:1. 准备请求 2. 批准请求。 接收者可以选择忽略请求而不影响一致性。只有在允许的情况下,它会回应准备请求和批准请求(在没有承诺不允许的情况下)。亦即以下

P1a: 如果对大于数值n的准备请求没有被承诺过,那么一个接收者可以批准序号为n的提议。

很明显P1a已经包含了P1。

至此我们已经完成了一个一致性协议算法,保证最终得到一个唯一的提议值。最终的算法只要加上下面的一些小优化即可。

一个已经对大于序号n的提议作出承诺的接收者,如果它收到序号为n的提议的准备请求时,选择忽略它。同样如果接收者已经批准过一个提议,那么针对该提议的准备请求时也选择忽略它(可能由于网络问题等原因而导致消息重发)

基于以上的优化,接收者只要记录当前批准过的最大序号的提议以及提议值,还有它所承诺过的最大序号的提议即可。由于P2c的要求,接收者需要记录它的信息以防止由于失败而需要重启导致忘记它做过的承诺和批准过的提议信息。

那么我们重新来整理一下该一致性协议算法:

  1. 阶段1

    1. 提议者选择一个序号n,并把该序号用准备请求的方式发给大多数的接收者
    2. 如果接收者接收到该序号的准备请求,并且该序号比它之前承诺过的序号都大,那么该接收者对该序号进行响应;如果该接收者之前批准过序号小于n的提议,那么就返回批准过的最大序号提议(包含序号和提议值)。
  2. 阶段2

    1. 如果前述提议者收到大多数的接收者的准备请求响应,那么它就产生一个提议(n, v)并把该提议发给接收者请求批准。对于v的选取,如果阶段1返回的响应中包含提议,那么选取序号最大的提议的提议值作为v,如果响应中没有包含提议,那么该v值可以随意选取。
    2. 如果一个接收者接收到一个序号为n的提议的批准请求,只要它未对序号大于n的提议进行过承诺,那么它就批准该请求。

总结完该算法后,原文还提了一下性能的优化:提议可以随时被抛弃而不影响准确性,如果已经有别的提议者开始生产更大序号的提议时,这时小序号的提议者可以考虑放弃原有的小序号提议。所以一个接收者如果收到一个较小的序号提议时应该告知提议者,已经有更大序号的提议被承诺过了。这样,原先小序号提议者就可以快速放弃进而产生大序号的提议。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值