Chinaunix首页 | 论坛 | 博客
  • 博客访问: 452655
  • 博文数量: 80
  • 博客积分: 2301
  • 博客等级: 大尉
  • 技术积分: 884
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-16 20:07
个人简介

I\'m interested in mathematics and Daoism. Welcome to talk about these subjects with me.

文章分类

全部博文(80)

文章存档

2017年(2)

2016年(16)

2015年(4)

2014年(6)

2013年(22)

2012年(2)

2011年(1)

2010年(4)

2009年(20)

2008年(2)

2007年(1)

我的朋友

分类: 云计算

2014-02-05 12:55:56

Paxos算法的一个容易理解的数学证明

The Paxos algorithm, when presented in plain English, is very simple. 

--- inventor of paxos algorithm


    Leslie Lamport 在文献[1]中提出了解决分布式系统中一致性问题的paxos算法,在那里通过讲述古希腊的paxos议会达成一致投票来讲解算法的.后来在文献[2]又给出了一个简单的说明.

    本文对文献[2]中论说的算法给出了一个更加直观,适合工程技术人员阅读的数学证明.


1 算法要解决的问题

     假定有有限多个进程,可能提出一些"建议".所谓一致性算法就是要能够保证:在建议的不同的值之中,最终只能有一个被确定下来.

    每一个进程有以下三种可能的身份:建议者(proposer),接受者(acceptor),学习者(learner).每一个进程可能有不只一个身份.如果不之名是哪一个身份,就以agent泛指.

    建议者可以提出一个建议,即提议一个"值".接受者,可以建议者的建议,做出响应:接受或者拒绝(后面有详述).学习者最终能够知道确定的值是什么.


    进程之间可以进行网络通信.并做如下假定:

    1) 每一个agent进行某个"操作"(或说,对于任一个网络消息的响应)所需的时间可能是任意长,并且可能停止响应,然后重启程序.

     2) 每一个进程都有一些"非易失性"存储,即如硬盘,磁带等那样的在断电之后可以保存长久数据的存储设备.

    3) 网络消息的传送,可能需要任意长的时间,可能丢失,或者重复.但是消息并没有伪造,篡改的.(即没有所谓"拜占庭问题")


2 算法希望能到达的结果

    三个特性:

    2.1) 终止性. 每一个进程最终确定了一个值

    2.2) 同意性. 每一个进程确定的值是相同的

    2.3) 正确性  每一个所确定的值,是某个进程所"建议"的.即任一进程所确定的值,不是非法的.

    满足这三个条件的算法,足以在实践中使用.


3 paxos算法

    先对算法做一些说明,然后再叙述proposer的acceptor动作.算法希望经过proposer/acceptor的有限个动作以后,确定一个值.

    "确定一个值"意思是:有超过一半的acceptor都接受了同一个值.

    最后学习者在获知确定的结果.这部分不是本文的重点,不做详述.(在实践中,acceptor/proposer可以把确定的值通知给learner)

    建议者提交的每一个建议,都必须有一个"能排序的序号"(下文可能使用英文proposal number),对于不同的建议序号必须不一同.实现方法:1)建议者的序号,加时间做为二元组 .方法2:每一个建议者都确定一个编号(有限证书),它记录它已经发起的建议的个数,这个个数乘以建议者的个数再加上自己的序号.下面假定每一个建议的序号为自然数,并且递增.


    整个算法的运行过程是如下两个阶段的循环:

    阶段1.

        a) proposer选择一个"建议的序号"n,发送一个消息(称为prepare消息)给一定数量的acceptor.这个数量只要大于"acceptor的个数的一半".(注意是大于,不包括等于).

        b) acceptor收到proposer的prepare消息的时候,有两种可能.如果它以前收到过prepare消息,对比以前收到的prepare消息的"建议的序号"最大值, 跟收到的序号对比.

        如果收到的序号大于这个最大值,这个acceptor告诉proposer它已经收到的建议的值和序号(如果已经收到的话).否则不回应.


    阶段2.

        a) proposer的prepare消息收到的回应的个数,如果大于acceptor个数的一半,那么先判断是否已经"确定了一个值"(前面所说的:某这个值被超过半数的acceptor所接受).如果已经确定了一个值,那么一致性达到.否则, 它向这些(有回应的)acceptor发送accept请求:

        发送proposal number n 以及值v.其中的v这样确定:如果acceptor的回应中有若干个值(及其序号),那么选取最大序号的那个值;如果acceptor的回应没有值,那么这个proposer可以自己决定一个值.

    b) acceptor收到accept消息的反应有两种可能:

    如果此acceptor已经回应过的prepare消息的那个序号"大于"收到的建议的序号n,它就什么都不做.否则,接受并记录收到这个建议的序号,值v,以及这个proposer(这称作"承诺"机制).

    上述两阶段中,proposer可以随时主动放弃一个"建议",或者重新启动一个新的建议.

    那么proposer怎么知道,算法已经完成呢?方法之一是:proposer已经在阶段1中已经知道一致性协议已经达成以后,向每一个acceptor发送"询问"的消息.如果所有的有回应的acceptor的建议的值都一样(有个别acceptor可能已经崩溃,正在重启中,从而没有回应),那就认为算法已经结束.

    关于阶段1中的一致性已经达成,要做说明如下:如果再有一个proposer发送走过了阶段1,那么接收它的prepare消息的acceptor一定有一个是先前已经达成一致性协议中的某一个acceptor,所以此时,这个proposer一定会收到达成一致性的那个prpopsal 及其序号.在第二阶段中,只要使用这个proposal及其序号即可. 因为阶段1中,只要有过半的acceptor都一致即可认为是一致性已经达成(也正是因此,paxos算法可以在"少于一半"的acceptor停止工作的情况下,仍然可以正常运行).   


    考虑一个极端的情况.有一个proposer a,向编号为1,2,3,….m的m个acceptor发送了prepare消息,…成功走完第一阶段,正准备发送acceptor消息.这时,有另一个proposer b,想向1,2,…m这m个acceptor发送了prepare消息,走完第一个阶段.这时候,a再继续发送accept消息.根据上面来"两阶段"的描述,a向1,2,…m中的任一个提交的值,都无法成功.类似地,a可能导致b永远也无法导致某个值设置到1,2,..m上.

    这种极端情况如果有"无限次"出现的话,那就永远无法达成一致了.引入一个"时间窗口"的机制:算法开始之前,选定一个足够的值t表示时间.每一个acceptor收到prepare消息以后的t之内,不再收任何prepare消息.所以假定上面的极端情况不再发生.或者说有如下结论成立:

    (假设)当一个proposer在阶段2中向编号为1,2,….m的m个acceptor发送accept消息,一定存在一个acceptor i (1≤ i ≤ m),的值被设为值v,并且在这之前不是v. 

    另外,为了保证阶段中的acceptor的承诺起作用,我们还必须假定:对于两个建议propose_1, propose_2,如果propose_2 发现的时刻大于 propose_1的发起时刻,那么propose_2的序号大于propose_1的序号.即序号的大小代表了时间先后.(这在实践上相当于假定了每一个agent上都有一个时钟并且时钟的差别不大).关于时钟的问题,请参见文献[3].

4 paxos算法的新的证明.

    这里是要证明,任何一个proposer按照步骤1,2那样的循环进行,一定可以停止,即在阶段2中发现某个值被超过半数的acceptor所接受.

    这里给出一种新的数学证明,与paxos算法提出者Leslie Lamport的证明相比更容易理解.

    acceptor不妨假定有2m+1个,使用编号1,2,….2m+1分别代表.

    根据3中的"假设",任一个proposer走到阶段二的时候,至少使上述排列中的某一个元素的v发生变化.所以,一个proposer 经过有限个循环(走完两个阶段),一定可以使超过半数(不妨假设为m+1个)的acceptor的值都被设置了(即不再是空值).但是不同的acceptor被设置的值可能不同,原因在于可能出现以下类似的现象:

    当某个proposer a向编号为1,2,3…m的acceptor发送accept消息,成功给它设置了某个值value_1(其建议的序号记为proposal_number_1).此时有另一个proposer b向,2,3,4,…m, m+1,m+2这些acceptor发送prepare消息,其建议的序号为proposal_number_2 ,并且proposal_number_2 > proposal_number_1.当a向


    此时,m+1个acceptor已经被设置了值,另外一些acceptor还没有被设置值.

    不妨假设这m+1个acceptor每一个被设置的值都不同.当然也都不是空.这些值的序号也不相同.这些序号中最大的序号不妨记为max_proposal_number,其值记为max_value.于是,一定存在一个proposer曾经以序号max_proposal_number走过阶段1,阶段2,把这个max_value设置到某个acceptor上.

    此时,对于某个proposer(不妨称呼为a),如果走完了阶段1:proposer a收到的回应个数超过半数,于是它一定可以从某个acceptor处收到max_proposal_number及max_value.这个proposer在阶段2中,会使用一个新的序号n(大于max_proposal_number),把max_value 设置到一个新的acceptor上,使max_value出现的次数变大,同时满足:现在现有已经被设置了值的acceptor中,被设置的序号最大的那个序号所对应的值仍然是 max_value.

(注意:不同的序号,值可能是一样的).

    这样再有proposer(或者是a或者是其他的proposer)发起accept消息的时候,像上面分析一样,所选定的值,仍然是max_value.于是经过若干次个循环以后,一定会max_value出现的次数超过半数.


参考文献

[1] Leslie Lamport, The part-time parliament

[2] Leslie Lamport, paxos-simple

[3] Fischer, et al, The impossibility of distributed consensus with one faulty process 


阅读(3806) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~