美文网首页
Paxos算法介绍

Paxos算法介绍

作者: Chenzongshu | 来源:发表于2017-04-01 09:49 被阅读0次

    前言

    PAXOS是很多分布式系统的基石,获得图灵奖的Lamport的成名作就是关于paxos的算法,这算法也是出了名的难理解,但实际上 只是那篇论文写的难以理解...程序员直接看代码的话一下就明白了

    Paxos的前提假设是没有拜占庭将军问题

    写在前面的总结

    总体说来,paxos就是通过两个阶段确定一个决议:

    • Phase1:确定谁的编号最高,只有编号最高者才有权利提交proposal;
    • Phase2:编号最高者提交proposal,如果没有其他节点提出更高编号的proposal,则该提案会被顺利通过;否则,整个过程就会重来。你编号高,我比你更高,反复如此,算法永远无法结束,这叫活锁。

    FLP Impossibility已经证明,在异步通信中不存在任何一致性算法,活锁便是Paxos无法解决的硬伤。

    Phase1,Phase2非常像2PC中的两个阶段,因此paxos本质上是多个2PC交替执行!

    另外,即使你明白了,在实现时会知道有多难,工程实现与理论差距很大!

    Paxos协议是什么

    一个分布式系统(不可靠)就某个值或者决议达到共识一致的过程。该系统的网络状况或者节点状态完全不可靠。

    一致性是什么?
    简单的描述是: 有一个变量v,N个进程,每个进程都尝试修改v的值,它们的企图可能各不相同,例如进程A尝试另v=a,进程B尝试另v=b,但最终所有的进程会对v就某个值达成一致,即上述例子中如果v=a是v达成一致时的值,那么B上,最终v也会为a。
    需要注意的是某个时刻达成一致并不等价于该时刻所有进程的本地的v值都相同,有一个原因是进程可能挂掉,你不能要求挂掉的进程任何事;更像是最终所有存活的进程本地v的值都会相同。

    这个一致性需要满足三个要求:

    1、v达成一致时的值是由某个进程提出的。这是为了防止像这样的作弊方式:无论如何,最终都令每个进程的v为同一个预先设置好的值,例如都令v=2,那么这样的一致也太容易了,也没有任何实际意义。

    2、一旦v就某个值达成了一致,那么v不能对另一个值再次达成一致。这个要求称为安全性。

    3、一致总是能够达成,即v总会被决定为某个值。这是因为不想无休止的等待,这个要求也称为活性。

    Paxos协议具体规则

    角色:

    • proposer 提出提案,提案信息包括提案编号和提议的value;
    • acceptor 收到提案后可以接受(accept)提案;
    • learner 只能"学习"被批准的提案;

    每一个Proposer提出的建议都会被编号,且这个编号是全局严格全序的。

    一)proposer:

    Proposer p1在向acceptor提出关于X的第n号议案前,都会先向每一个acceptor 发送 promise请求——拒绝掉所有小于编号n的promise请求及accept请求(accept请求就是真正的提议案的请求)。

    二)acceptor:

    1、如果某个acceptor之前已经promise过其他proposer 且其议案编号 大于n,那么将会拒绝p1的promise请求;

    2、如果某个acceptor当前promise拒绝的议案编号小于n,那么就会接受p1的promise请求,并将当前acceptor accept的最新的议案编号及议案内容(即X的值)告诉proposer

    三)proposer:

    1、如果proposer p1获得了过半acceptor的承诺,则首先整合所有acceptor返回的信息,将acceptor中返回的最大编号的议案的内容作为自己的议案的内容(如果所有acceptor都没有返回议案内容,那么就自己随意设定一个),然后向所有acceptor发出自己关于X的accept请求;

    2、如果proposer没有获得过半数acceptor的回应,可以忽略这一次操作,申请一个新的议案编号,马上重新进行一遍整个操作

    四)acceptor:

    1、如果acceptor收到了proposer的accept请求时,还没有收到其他proposer更高编号的promise请求时,将会批准proposer的建议,并将自己决定告知learner;

    2、如果acceptor收到了proposer的accept请求时,已经收到了其他proposer更高编号的promise请求时,将会拒绝本次accept

    五)learner:

    Learner收到了某个acceptor的accept信息后,会统计一共收到了多少个acceptor发过来的该proposal的accept信息,若该proposal的acceptor数量达到了quorum,那么就认定该proposal对应的值为 X的值。

    Paxos小故事

    诸葛亮找刘备献策,提出有一色目人有一方法“Paxos”可以解决蜀国决策制度的缺陷。

    约束条件:

    诸葛亮:“民主是个宝呀,它能解决一切问题。决策者之间不分高下,所以既然想要他们保持一致,我们就要用投票,少数服从多数!”
    刘备:“怎么个投法?”
    诸葛亮:“如果主公手下五虎上将是五个决策者。。。”刘备:“那五个肌肉男?”
    诸葛亮:“正是,这证明即使五个头脑简单的武夫也能做好。”(五虎将齐打喷嚏。)
    诸葛亮:“谁提议新政令(提案者),谁就发起投票。我们保证,投票者必须是决策者中的大多数。”
    刘备:“怎么定大多数呢?”
    诸葛亮:“任意两次投票中,必须有重合的决策者,这就是大多数了。比如五虎将做决策者,每次政令通过中,必须有三个人或更多投票的人才能决定,这样两次投票中至少有一人都参加了,他就可以拍板!对提案者来说,如果大多数投票者都投赞成这个提议,法令就通过。”
    刘备沉重地说道:“孔明,万一总是凑不成大多数,岂不是耽误我们的现代化进程?民主,对中国国情来说,太复杂了。”

    诸葛亮又激动了:“主公,不复杂的,长远来看好处很明显,不要短视!如果能做到以个三个基本点,所有政令绝对不会出现不一致,而且不会出现无法进行下去的事。一、所有政令必须被提出后才能批准;二、一次提出政令的过程中,只能批准一条政令;三、书记官(负责永久记录政令的官员)只能学习已经批准的政令。只要做到这三点,肯定不会政令不一致!”
    刘备:“可是孔明,你在说什么呀?我只想知道决策者该怎么做。”
    诸葛亮自信满满:“别急主公,从数学上可以证明,只要满足上面三条,一定不会出现政令不一。当然,这三条太宽泛了,不能对决策者做出指导。我还有更加严格的约束。一、每个决策者必须接受他收到的第一个提议政令。”
    刘备:“凭什么呀?”诸葛亮:“我们要假定提议者已经搞清楚了一切,肯定是好提案啦。这不是我们的重点,别打断我。”
    诸葛亮:“二、一旦关于一件事,我们通过一条法令后,之后关于这件事通过的任何法令,都还得是这个法令。”
    刘备呆了下:“这不废话吗?”
    诸葛亮自信满满:“虽然是废话,但你想,保证了这第2条,是不是所有的政令都必须一致呀?”
    刘备:“可是对决策者没指导意义呀。”
    诸葛亮自信满满:“是的,所以,我们加强约束,三、如果一条法令批准后,之后每一个决策者如果关于这件事又通过法令,那这个法令还得是同一条。”
    刘备傻了:“你说得是没错,可这有什么用呢?”
    诸葛亮自信满满:“所以继续加强约束:四、如果一条法令被批准通过了,之后提议者关于这件事,又提新法令,必须还得是同一个法令。”
    刘备怒了:“孔明我想揍你了,你说这些有个屁用啊!”
    诸葛亮自信满满:“别急主公,现在我要祭出最强约束条件作为我的奥义了:五、每个提案都得有个独一无二的编号,如果编号N的提案通过了,那么大多数决策者们,要么从没接受者编号小于N的任何提议,要么最近一次批准通过的法令就是这个提案。”
    刘备开始追打诸葛亮:“孔明你个坏人,你玩我呀!这屁话你对我说!”
    诸葛亮边逃边喊:“wiki里就是这么解释的,哎,主公你不懂数学别打我嘛。Leslie的论文也是这么写的。。。”

    Paxos执行流程

    刘备:“真爽,孔明你手感不错。说点实在的吧,不懂的东西少扯。”
    诸葛亮:“主公,你不懂数学嘛。好吧,我来说说paxos算法的流程,就三段式,六个步骤而已。角色包括,提案者,决策者,书记官(学习政令的)。

    一、提案者先从主公那里搞到个独一无二的编号,例如N。找到决策者们的多数派,就说五虎将吧,找到三个肌肉男先。假设,这个提案者来自成都,想提的是,外地蜀国将级官员不得无故进入魏国使者驻蜀驿馆。那么,提案者发给三个五虎将,提案中说,我现在有个编号N的提案,关于蜀国高级将领进出魏国使者驿馆的事,请回答我。”

    二、五虎将们收到了关于使者驿馆事件的提案,编号是N。其中任一个决策者,比如赵云,他在收到N提案后,首先检查,之前关于魏国使者驿馆事件,有没有收到过提案啊?如果没收到,当然回复提案通过,同时赵云拿出自己的小本本记上,已经回复编号N的提案。如果收到过关于驿馆事件的编号M的提案,就检查编号M,如果M大于N,那么跟信使说,我拒绝这个提案。如果M小于N,回复通过,并且说,关于这事,上次我已经收到了编号M的提案了。

    三、提案者如果收到多数决策者的通过回复,就开始正式提议了。这时,先检查五虎将的回复,如果都简单的回复通过,那么就正式提议之前想提议的《蜀国将级官员不得无故进入魏国使者驻蜀国驿馆》提案。如果决策者们不是简单的回复通过,而是说:这次我赵云通过了,但是我曾经回复过编号M的提案。这样,提案者需要从这次决策者们的回复中,找出所有编号M中的最大值。假设就赵云复杂的回复了,其他四人都是简单的回复通过。那么,提案者这次不能正式提议自己原来想提的,而要提议编号M对应的提案。

    四、同第二步骤一样,五虎将们根据二步骤的准则,选择通过还是不通过。

    五、提案者如果发现多数决策者同意了,意味着法令通过,这时他要记录法令,同时告诉书记官们。

    六、书记官们在羊皮纸上记录法令。“

    Paxos各个角色做的事

    刘备搔搔头:“孔明,你再说说提案者,决策者要做的事吧,书记官的很简单,就不用说了。”
    诸葛亮:“主公,书记官的工作不简单啊,信使会传丢消息的,书记官也会生病的。我们既要在法令通过时主动通知书记官,又要允许书记官在对法令不清楚时过来主动询问。不过,既然主公想多了解提案者和决策者的工作,我就来详细说说。

    一、提案者。首先他得从主公那搞来一个独一无二的编号。”
    刘备:“我很忙的孔明,我是一把手哎。”
    诸葛亮有些无奈:“就光给编号也不干呀!那让他们自己维护自己的编号吧,遇到编号相同时,按级别排序,例如按关羽、张飞、赵云、马超、黄忠排序。然后要找到五虎将的多数派,例如关张赵这三人,发自己要决定的事以及编号过去。这是第一步。在第三步时,又到了提案者要做工作了。如果关羽又不响应自己了,那么再发给黄忠问问看。直到有大多数人响应自己。对于响应的处理,有以下情况:
    A、这些响应中,如果有人明确拒绝,比如赵云说,关于驿馆事件,我已经批了编号大于N的提案,那么这次提案最好就放弃吧,或者加大自己的编号,重复第一步再提!
    B、张飞说我可以通过,但是之前我批准过驿馆事件编号小于N的提案,内容是允许进入达到政治避难目的。那么,这次提案内容必须变更为张飞之前提交的方案。
    C、所有人都无条件通过。继续正式提交自己的方案。
    到第五步,如果多数派批准了,那么方案正式成为法令。提案者要告诉书记官记录哦。”
    刘备:“你这么说我就明白了嘛。多简单?先前搞七搞八的说了一大通。”
    诸葛亮:“唉,先前的证明嘛。当然,微软还搞了个两段式提交,号称fast paxos,那个雅虎的zookeeper也是的,其实也就对第五步做了优化。主公,不要打我,你不用管我刚才说了什么。我们继续说决策者的工作。
    第二步,决策者开始工作了。例如还是说赵云,他在收到N提案后,首先检查,之前关于魏国使者驿馆事件,有没有收到过提案啊?如果没收到,简单的回复提案通过,同时赵云拿出自己的小本本记上,已经回复编号N的提案。赵云同时承诺,以后收到编号小于N的关于驿馆事件的提案,保证不批!如果收到过编号M的提案,检查这上次编号M,如果M大于N,那么跟信使说,我拒绝这个提案。如果M小于N,回复通过,并且说,关于这事,上次我已经收到了编号M的提案了。
    第四步决策者批准时也和上面一样。不过fast paxos等两段式的paxos改进算法,在这里决策者们已经可以记录法案了。”
    刘备:“好孔明!我有些明白了,不过光说不练假把式,演习下吧。把五个肌肉男叫来,你我来提案,外加捣乱,你可以用你的跑车撞信使了,看看是否出现不一致。”
    诸葛亮:“No problem。

    相关文章

      网友评论

          本文标题:Paxos算法介绍

          本文链接:https://www.haomeiwen.com/subject/ytfiottx.html