Paxos 总结 (三) Paxos Made Simple

前言:

在常见的分布式系统中,总会发生诸如机器宕机或网络异常等情况。Paxos 算法需要解决的问题是如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发送以上任何异常,都不会破坏整个系统的一致性。


由于拜占庭将军问题(见第一篇文章)的存在,想要达成一致性状态是不可能的,但是在实际工程角度,可以通过设计来避免拜占庭将军问题,如通过局域网,和对内容加密与验证等方式防止内容被篡改。这样才有了paxos的实际意义。


参与者(一个进程可以同时是三种角色):

proposer:提出提案的进程。

acceptor:接收提案并决定是否可以通过的进程。

learner:接收被选择的提案的进程。


术语:

提案:如提案A{id:1,value:set a = 5}。

通过:acceptor同意的提案。

选定:超过半数acceptor通过,并最终决定的提案。


一.问题描述(需求提出)

假设有一组可以提出提案的进程集合,那么对于一个一致性算法并且考虑安全性来说需要满足以下几点:

  • 在这些被提出的提案中,只有1个会被选定。
  • 只有被提出的提案才能被选定(安全性)。
  • 如果某个进程认为某个提案被选定了,那么这个提案是真的被选定的那个(安全性)。
  • 如果没有提案被提出,那么就不会有提案被选定。
  • 当一个提案被选定,进程应该可以获取被选定的提案信息。
系统存在以下情况
  • 每个参与者以任意的速度执行,并且可能在任何环节会因为出错而宕机,也可能会重启。
  • 消息在传输过程中可能会出现不可预知的延迟,也可能会重复发送或者丢失,但是消息不会损坏,即消息内容不会被篡改(非拜占庭问题)。

二.推导过程

注意:以下所有推导过程都认为是在一个从提出-通过-选定-最终被学习的一个一致性环节当中。比如什么之后所有之类的话,都是在本环节内。当所有 Learner 都完成了同步,新的提案又开始了。

P1:任何一个Acceptor 必须通过它收到的第一个提案。

这是如果集群中只有1个提案被提出,且需要最终被选择而必须满足的条件。


但是:

如果有多个不同的提案(key和value都不相同)被不同的Proposer同时提出,根据P1条件,那么这就可能会导致每个Acceptor批准了他收到的第一个提案,而最终没有一个提案是被多数Acceptor通过的,也就没有任何一个提案被选定,如图所示就是这样的场景:




所以:

即要满足P1又要满足多于半数的Acceptor通过,则可以定义如下约定:


P2:如果一个提案被选定,那么所有比这个提案编号大的,且被 选定 的提案,其Value是同一个。


如果一个提案被选定,那么这个提案肯定至少被一个Acceptor 通过。那么可以通过以下约定推导出P2:


P2a如果一个提案被选定,那么所有比这个提案编号大的,且被 通过 的提案,其Value是同一个。


我们仍然需要 P1 来保证提案会选定,但是因为通讯是异步的,一个提案可能会在某个 Acceptor 还未收到任何提案时被选定了,如图所示:

如上图所示,在 Acceptor 1 没有收到任何提案的情况下,其他4个 Acceptor 已经批准了来自 proposer 2的提案,而此时 proposer 1 产生了一个具有其他 value 值的、编号更高的提案,并发送给 Acceptor 1。根据P1,就需要 Acceptor 1 通过该提案,但是这又和 P2a 矛盾了,因此需要同时满足 P1 和 P2a ,需要对 P2a 进行优化:


P2b:如果一个提案被选定,那么其后任何 Proposer 产生的编号更高的提案,其值都是同一个。


因为一个提案必须在被 Proposer 提出后才能被 Acceptor 通过,因此 P2b 包含了 P2a,进而包含了 P2。下面看下怎么论证 P2b 成立。


为了发现如何保证P2b,我们来看看如何证明它成立。我们假设某个具有编号m和value值v的提案被选定了,需要证明具有编号n(n>m)的提案都具有value值v。我们可以通过对n使用归纳法来简化证明,这样我们就可以在额外的假设下—即编号在m…(n-1)之间的提案具有value值v,来证明编号为n的提案具有value值v。因为编号为m的提案已经被选定了,这意味着肯定存在一个由半数以上的acceptor组成的集合C,C中的每个acceptor都通过了这个提案。再结合归纳假设,m被选定意味着:


C中的每个acceptor都通过了一个编号在m…n-1之间的提案,每个编号在m…n-1之间的被acceptor通过的提案都具有value值v, 因为任何包含半数以上的acceptor的集合S都至少包含C中的一个成员,我们可以通过维护如下不变性就可以保证编号为n的提案具有value v:


P2c:对于任意的n和v,如果编号为n和value值为v的提案被提出,那么肯定存在一个由半数以上的acceptor组成的集合S,可以满足条件 a) 或者 b) 中的一个:

a)S中不存在任何的acceptor通过过编号小于n的提案

比如值为v的提案被第一次提出

b)v是S中所有acceptor通过的编号小于n的具有最大编号的提案的value值。

如果值为v的提案不是第一次被提出,那么编号比他小的提案中最大的一个编号的值也是v


实际上P2c规定了每个Proposer 如何产生一个提案,对于产生的每个提案(n,v)需要满足这个条件“存在一个由超过半数的Acceptor 组成的集合S:要么S中没有人批准(accept)过编号小于 n 的任何提案,要么S的任何acceptor批准的所有议案(编号小于n)中,v是编号最大的议案的决议”。当Proposer遵守这个规则产生提案时,就可以保证满足P2b。下面我们通过数学归纳法来证明P2c:


首先假设提案(m,v)被选定了,设比该提案编号大的提案为(n,v’),我们需要证明的就是在P2c的前提下,对于所有的(n,v’),有v’=v。


(1)n=m+1时,如果有这样编号的提案,首先我们知道(m,v)被选定了,这样就不可能存在一个S且S中没有人批准过小于n的提案[S与批准(m,v)的Acceptor集合肯定有交集],那v’只能是多数集S中编号小于n的最大编号的那个提案的值了,此时n=m+1,理论上小于n的最大的编号肯定是m,同时由于S和通过(m,v)的acceptor集合都是多数集,就保证了二者肯定有交集,这样Proposer在确定v’取值时,肯定选到就是v。
上面实际上就是数学归纳法的第一步,确切的说是使用的是第二数学归纳法。上面是第一步,验证了某个初始值成立。下面,需要假设编号在[m+1,k-1]区间内成立,并在此基础上推出n=k上也成立。

 

(2)根据假设编号在[m+1,k-1]区间内的所有提案都具有值v,需要证明的是编号为k的提案也具有值v。根据P2c,首先同样的不可能存在一个S且S中没有人批准过小于n的提案,那么编号为k的value值,只能是一个多数集S中编号小于n的最大编号的那个提案的值,如果这个最大编号落在[m+1,k-1]区间内的,那么值肯定是v,如果不是落在[m+1,k-1]区间,那么它的编号肯定就是m了,不可能比m再小了,因为S也肯定会与批准(m,v)的Acceptor集合肯定有交集,那么它的编号值就不会比m小,而编号如果是m那么它的值也是v。由此得证。


三.流程描述

1.prepare

proposer选择一个新的提案编号n,然后向某个acceptors集合的所有成员发送请求,要求这些acceptor做出如下回应:
(a).保证不再通过任何编号小于n的提案
(b).返回当前它已经通过的编号小于n的最大编号的提案,如果存在的话

2.accept

如果proposer收到了来自半数以上的acceptor的响应结果,那么它就可以产生编号为n,value值为v的提案,这里v是所有响应中编号最大的提案的value值,如果响应中不包含任何的提案那么这个值就可以由proposer任意选择。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值