精华内容
下载资源
问答
  • paxos

    2016-08-06 09:56:34
  • Paxos

    千次阅读 2021-01-02 19:06:03
    Paxos算法 一致性算法背景 分布式环境中最突出的特点就是其不可靠性,如何在这种环境中解决多个节点并发操作数据并需要保证在读写过程中数据的一致性问题,是一致性算法被提出的初衷。Paxos算法是Lamport提出的一...

    Paxos算法

    一致性算法背景

    分布式环境中最突出的特点就是其不可靠性,如何在这种环境中解决多个节点并发操作数据并需要保证在读写过程中数据的一致性问题,是一致性算法被提出的初衷。Paxos算法是Lamport提出的一种基于消息传递的分布式强一致性算法,它的目的在于解决分布式环境下一致性的问题。

    Mulit-Master多监督节点方式是保证分布式系统可用性(Availability)的一种策略,避免单点故障问题,但是也带来了一致性(Consistency)的问题。保证多节点并发访问分布式数据一致性主要有两种方式,分别是复制与同步多数派

    复制与同步有三种情况,包括主从异步复制、主从同步复制和主从半同步复制如下表所示:

    类型

    过程

    缺点

    主从异步复制

    Master接收写请求;Master写入本磁盘;Master向Client应答写入操作执行完成;Master复制数据到从库。

    如果磁盘在复制前损坏将导致数据丢失。

    主从同步复制

    Master接收写请求;Master复制日志到从库;Master等待,直到所有从库都返回。

    不会发生数据丢失,但是一个失联节点会造成整个系统不可用,保证了一致性,单可用性降低了。

    主从半同步赋值

    Master接收写请求;Master复制日志到从库;Master等待,特定数量的从库返回写入执行成功,向Client应答写入执行成功。

    具有高可用性,但是可能存在任何从库都不完整的情况。

    多数派读/写的基本思想是每次写入操作保证写入大于等于N/2+1个节点,节点之间平等;每次读取保证读写节点个数大于N,从大于等于2N+1个节点读取,容忍最多(N-1)/2个节点损坏。法定集合从理论层面说明了多数派的思想,其定义为将一个超过半数的集合称之为法定集合,比如数字1、2、3、4、5,共5个元素,{1,2,3}有三个元素就是法定集合。法定集合的性质:任意两个法定集合,必定存在一个公共的成员法定集合的概念有利于加深对Paxos算法的理解,Paxos算法通过多个监督者来增强可靠性,其基本思想是通过监督者们的投票来表决数据的状态变化,并保证所有对数据的访问都遵从这种表决。

    Paxos算法

    Paxos算法背景

    Paxos算法是二段提交原则(2PC),每个Proposer在发送自己的提案之前,先检查有没有已经提议且被批准的值,如果有则放弃自己的提案,这样最终只有一个值被批准。这就可能存在检查到多个值被批准的情况,例如并发环境中两个申请者(Proposer) P1和P2,P1想提议将实例value的值设置为red,P2想提议将value设置为blue,共有5个决策者(Acceptor) A1~A5。接着,P1在发送提案前,检查后发现自己没有值被批准,因此提议red。同时,在所有Acceptor批准之前,P2也进行提议,它也检查出自己没有值被批准,所以P2也把自己的blue作为提案发送给Acceptor。然后,P2的提案优先到达A1、A2和A3,这些Acceptor先批准了blue ,已经达到多数,所以blue被批准。但是随后A3、A4、A5接收到了red,也予以批准。这就出现了多个值被批准的不一致情况。

    考虑上述问题的一种解决方式是,一旦Acceptor批准了某个值,其他有冲突的值都应该被拒绝,即A3对随后到达的red应拒绝。Acceptor采用高优先级优先的策略进行选择与拒绝,使用Proposal唯一ID的方式对Proposal进行优先级排序,Acceptor批准优先级高的值,拒绝低优先级的Proposal 。这样,在Proposer发送Proposal之前,就需要生成一个唯一ID,而且需要比之前已经使用的或生成的都要大。

    上述背景就是Paxos算法解决分布式一致性问题的基本思想,即通过二段提交和高优先级选择策略解决分布式系统中的各个进程如何就某个值或提案(Proposal)达成一致的问题。为此,Paxos算法有两个约束条件(a) 每个Acceptor必须接受他收到的第一个提案;(b) 在一个多数派中,当所有Acceptor都没有批准过编号小于N的任何提案,或者它们批准的提案中编号小于N的最大编号的提案值是C时,Proposer才能提出一个一个编号为N值为C的提案。以此为基础,Paxos算法可以保证在任意时刻,就算存在多个Proposer在询问之后提出了不同值的提案,最终只有其中一个Proposer的提案值会被法定集合接受者接受,即只有一个值会被决定;另外,被决定值会进行传播,即当value的值被决定后,假设被决定为C,之后任意的proposer提出的提案值也是C。

    Paxos算法流程

    Paxos将一次Paxos算法执行称为一个实例Instance,将有Proposer发起但是没有获得批准的议案称为提案Proposal,将最终被批准通过的议案中的值称为决议Value。另外,Paxos将系统中的角色分为三类,分别是提议者Proposer,决策者Acceptor,和最终决策学习者Learner

    • Proposer:提出提案 (Proposal) ,其中包括提案编号 (Proposal ID) 和提议的值 (Value)

    • Acceptor:参与决策,审批Proposers的提案,收到Proposal后对其进行选择,若Proposal获得多数Acceptors的接受,则称该Proposal被批准

    • Learner:不参与决策,从Proposers/Acceptors学习最新达成一致的提案和被批准的值(Value) ,在一个Paxos算法实例中,只会批准一个Value

    Paxos算法主要分为两个阶段,第一阶段:Prepare阶段,Acceptors接收请求产生判断、并向对应的Proposer返回承诺,Proposer依据返回的承诺决定是否继续更新数据而进入下一阶段的请求。第二阶段:Accept阶段,Acceptors接受更新请求并完成多副本更新。具体算法流程如下图所示:

    Prepare 阶段 Proposer生成一个全局唯一且递增的提案编号N,并将 Prepare 请求发送给Acceptors中的一个多数派;Acceptor收到 Prepare 消息后,如果提案编号小于它已经回复的编号,则拒绝该Prepare消息;如果提案的编号大于它已经回复的所有Prepare消息,则Acceptor将自己上次接受的提案回复给Proposer,并做出两个承诺 (Promise),一个应答 (Response) 承诺不再接受提案编号小于等于 N 的Prepare请求,承诺不再接受小于 N 的Propose请求,应答已经接受过的提案中ID编号最大提案的Value和Proposal ID,没有则返回空值。这一阶段有两个目的,一是Proposer检查询问自己是否有被批准的值,如果有就改用被批准的值;Acceptor如果有在此之前的提案没有被批准,则根据提案编号阻塞掉他们,从而不让它们与其自身发生竞争。

    Accept阶段当一个Proposer收到了多数Acceptors对Prepare请求的回复后,就进入Accept批准阶段。它要向回复Prepare请求的Acceptors发送Accept请求,包括编号N和根据Prepare阶段决定的Value,Proposer也会收到其他Accept上一阶段给出的承诺。在不违背自己向其他 Proposer的承诺的前提下,Acceptor收到 Accept 请求后即接受并持久化当前Proposal ID和提案Value。如果Acceptor收到一个编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。如果N小于Acceptor已经响应的prepare请求,则拒绝,不回应或回复Error。当Proposer没有收到多数Acceptors的回应,就会递增提案ID重新进入Prepare阶段,并重新提出prepare请求。

    最后 Proposer 收到多数Acceptors的Accept之后,决议形成,将形成的决议发送给所有Learners。

    从系统角色的角度理解上述Paxos算法流程

      Proposer 提议者 Acceptor 接受者
    询问阶段 询问法定集合进程的自身value值 回复自身value的值
    预提案阶段 发送包含自身ID编号的预提案给法定集合接受者; 处理预提案,如果收到的预提案ID编号大于自身记录的ID编号,则更新自身记录的ID编号,并接受该预提案,否则拒绝这个预提案
    提案阶段 发送的预提案得到一个法定集合接受者的回复后,如果在询问阶段,法定集合的接受者均未批准给value赋予值,那么提议者拥有自由赋值的权利;否则,提议者从给出的值中中选择一个值赋予给value。假定自由赋予或者选择的值为C,发送包含C和自身ID编号的提案给接受者。 处理提案:如果收到的提案的ID编号大于等于自身记录的ID编号,那么更新ID编号,并接受该提案,记录的Value值为提案中的值

    Proposer在询问和预提案阶段都是向法定集合进程发送消息并获取回复,收到询问和预提案回复后再进行选值,所以,可以把询问和预提议阶段合并预提案附带询问功能,即为Prepare阶段。对应的Acceptor在处理询问时,要在根据规则接受预提案后,将询问结果和预提案接受结构在一个消息中回复给Proposer,称这个消息为诺言,诺言中包含了Acceptor记录的value值。可以看出无论是提案还是预提案,Acceptor只接受提案ID编号比它自身记录的ID编号更大的消息。

    Paxos算法分析

    总体说来,Paxos算法就是通过两个阶段确定一个决议,Prepare阶段:通过询问和回复确定谁的编号最高,只有编号最高者才有权利提交Proposal,会阻塞低编号的预提案;Accept姐u但:编号最高者提交Proposal,如果没有其他节点提出更高编号的Proposal,则该提案会被顺利通过;否则,整个过程就会重来。

    Paxos算法中决议的传播

    区别于一般选举逻辑,Paxos算法中每个Proposer不是执着于让自己的提议通过,而是要让提议尽快达成一致意见。例如,存在两个提议者PA和PB,如果PA在询问时发现某个Acceptor已经接受过先于其进行询问的PB的提议,即PA询问得到的是Acceptor对PB的诺言,这时PA会把自己的提议改为PB的提议。

    基于上述示例可能存在一种情况是,PA收到了其发出提议的法定集合中多个Acceptor的返回意见,且这些返回意见中存在多个接受者对于其他提议者的诺言。这时,PA需要处理接受与拒绝的问题,要在它们之间做出选择,当PA收到接受者的诺言是,一般接受者会告知已承诺的提案该被接受提案的ID编号两项信息,PA基于此选择ID编号较大的诺言作为自己的提案。

    Paxos算法中的Proposal编号

    整个Paxos算法基本上就是围绕着Proposal编号在进行,Proposer要不断选择更大的编号提交Proposal;Acceptor需要不断比较收到的Proposal编号是否最大,当编号确定了,就可以确定所对应的Value值。

    所以Proposal编号对Paxos算法至关重要,但是在分布式环境中,编号的产生就是一个棘手的问题,当多个Proposer并发地进行提案提交,怎么保证编号的唯一性在分布式环境中是一个比较复杂的问题。Chubby提出了一种Paxos提案ID编号的生成算法,假设N个Proposer的节点编号为 ir 取值大于等于0小于N,则Proposal的ID编号 S 的取值应该大于该Proposer已知的最大值,并且满足公式S \ $\% N = ir,其中Proposer已知的最大值来自Proposer对编号自增后的值接收到Acceptor的拒绝后所得到的值两部分。

    Paxos算法的活锁问题

    Proposal编号除了在产生过程中存在问题,在其更新过程中也有需要解决的冲突。当某Proposer提交的Proposal被拒绝时,可能存在因为Acceptor承诺返回了更大编号的Proposal,该Proposer提高Proposal编号继续提交的情况。一旦出现这种情况,两个Proposer都发现自己的编号过低转而提出更高编号的Proposal,显而易见。这会导致死循环,该现象被称为活锁。用一句通俗的话来描述活锁现象你编号高,我再比你更高,反复如此,算法永远无法结束

    Paxos算法中给出的解决活锁的办法是选举出一个Proposer作Leader,所有的Proposal都通过Leader来提交,当Leader宕机时马上再选举其他的Leader。通过Leader选举相当于把一个分布式问题转化为一个单点问题,而单点的正确性和健壮性由选举机制保证。Leader通过控制提交的进度来解决活锁现象:如果之前的Proposal还没有结果,之后的Proposal就稍微等待,而不是急于提高编号再次提交。

     

    Reference

    Paxos Made Simple

    Paxos算法详解

    展开全文
  • PAXOS

    千次阅读 2018-06-08 14:45:12
    Paxos算法是莱斯利·兰伯特(英语:Leslie Lamport,LaTeX中的“La”)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。问题和假设分布式系统中的节点通信存在两种模型:共享内存(Shared memory)...

    Paxos算法莱斯利·兰伯特英语:Leslie LamportLaTeX中的“La”)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。

    问题和假设

    分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复,在基础Paxos场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。Paxos算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。因此从20世纪80年代起对于一致性算法的研究就没有停止过。

    为描述Paxos算法,Lamport虚拟了一个叫做Paxos的希腊城邦,这个岛按照议会民主制的政治模式制订法律,但是没有人愿意将自己的全部时间和精力放在这种事情上。所以无论是议员,议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议或者传递消息的时间。但是这里假设没有拜占庭将军问题(Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息);只要等待足够的时间,消息就会被传到。另外,Paxos岛上的议员是不会反对其他议员提出的决议的。

    对应于分布式系统,议员对应于各个节点,制定的法律对应于系统的状态。各个节点需要进入一个一致的状态,例如在独立Cache对称多处理器系统中,各个处理器读内存的某个字节时,必须读到同样的一个值,否则系统就违背了一致性的要求。一致性要求对应于法律条文只能有一个版本。议员和服务员的不确定性对应于节点和消息传递通道的不可靠性。

     算法

     算法的提出与证明

    首先将议员的角色分为proposers,acceptors,和learners(允许身兼数职)。proposers提出提案,提案信息包括提案编号和提议的value;acceptor收到提案后可以接受(accept)提案,若提案获得多数acceptors的接受,则称该提案被批准(chosen);learners只能“学习”被批准的提案。划分角色后,就可以更精确的定义问题:

    1. 决议(value)只有在被proposers提出后才能被批准(未经批准的决议称为“提案(proposal)”);
    2. 在一次Paxos算法的执行实例中,只批准(chosen)一个value;
    3. learners只能获得被批准(chosen)的value。

    另外还需要保证progress。这一点以后再讨论。

    作者通过不断加强上述3个约束(主要是第二个)获得了Paxos算法。

    批准value的过程中,首先proposers将value发送给acceptors,之后acceptors对value进行接受(accept)。为了满足只批准一个value的约束,要求经“多数派(majority)”接受的value成为正式的决议(称为“批准”决议)。这是因为无论是按照人数还是按照权重划分,两组“多数派”至少有一个公共的acceptor,如果每个acceptor只能接受一个value,约束2就能保证。

    于是产生了一个显而易见的新约束:

    P1:一个acceptor必须接受(accept)第一次收到的提案。
    

    注意P1是不完备的。如果恰好一半acceptor接受的提案具有value A,另一半接受的提案具有value B,那么就无法形成多数派,无法批准任何一个value。

    约束2并不要求只批准一个提案,暗示可能存在多个提案。只要提案的value是一样的,批准多个提案不违背约束2。于是可以产生约束P2:

    P2:一旦一个具有value v的提案被批准(chosen),那么之后批准(chosen)的提案必须具有value v。
    

    注:通过某种方法可以为每个提案分配一个编号,在提案之间建立一个全序关系,所谓“之后”都是指所有编号更大的提案。

    如果P1和P2都能够保证,那么约束2就能够保证。

    批准一个value意味着多个acceptor接受(accept)了该value.因此,可以对P2进行加强:

    P2a:一旦一个具有value v的提案被批准(chosen),那么之后任何acceptor再次接受(accept)的提案必须具有value v。
    

    由于通信是异步的,P2a和P1会发生冲突。如果一个value被批准后,一个proposer和一个acceptor从休眠中苏醒,前者提出一个具有新的value的提案。根据P1,后者应当接受,根据P2a,则不应当接受,这中场景下P2a和P1有矛盾。于是需要换个思路,转而对proposer的行为进行约束:

    P2b:一旦一个具有value v的提案被批准(chosen),那么以后任何proposer提出的提案必须具有value v。
    

    由于acceptor能接受的提案都必须由proposer提出,所以P2b蕴涵了P2a,是一个更强的约束。

    但是根据P2b难以提出实现手段。因此需要进一步加强P2b。

    假设一个编号为m的value v已经获得批准(chosen),来看看在什么情况下对任何编号为n(n>m)的提案都含有value v。因为m已经获得批准(chosen),显然存在一个acceptors的多数派C,他们都接受(accept)了v。考虑到任何多数派都和C具有至少一个公共成员,可以找到一个蕴涵P2b的约束P2c:

    P2c:如果一个编号为n的提案具有value v,那么存在一个多数派,要么他们中所有人都没有接受(accept)编号小于n 
    的任何提案,要么他们已经接受(accept)的所有编号小于n的提案中编号最大的那个提案具有value v。
    

    可以用数学归纳法证明P2c蕴涵P2b:

    假设具有value v的提案m获得批准,当n=m+1时,采用反证法,假如提案n不具有value v,而是具有value w,根据P2c,则存在一个多数派S1,要么他们中没有人接受过编号小于n的任何提案,要么他们已经接受的所有编号小于n的提案中编号最大的那个提案是value w。由于S1和通过提案m时的多数派C之间至少有一个公共的acceptor,所以以上两个条件都不成立,导出矛盾从而推翻假设,证明了提案n必须具有value v;

    若(m+1)..(N-1)所有提案都具有value v,采用反证法,假如新提案N不具有value v,而是具有value w',根据P2c,则存在一个多数派S2,要么他们没有接受过m..(N-1)中的任何提案,要么他们已经接受的所有编号小于N的提案中编号最大的那个提案是value w'。由于S2和通过m的多数派C之间至少有一个公共的acceptor,所以至少有一个acceptor曾经接受了m,从而也可以推出S2中已接受的所有编号小于n的提案中编号最大的那个提案的编号范围在m..(N-1)之间,而根据初始假设,m..(N-1)之间的所有提案都具有value v,所以S2中已接受的所有编号小于n的提案中编号最大的那个提案肯定具有value v,导出矛盾从而推翻新提案n不具有value v的假设。根据数学归纳法,我们证明了若满足P2c,则P2b一定满足。

    P2c是可以通过消息传递模型实现的。另外,引入了P2c后,也解决了前文提到的P1不完备的问题。

     算法的内容

    要满足P2c的约束,proposer提出一个提案前,首先要和足以形成多数派的acceptors进行通信,获得他们进行的最近一次接受(accept)的提案(prepare过程),之后根据回收的信息决定这次提案的value,形成提案开始投票。当获得多数acceptors接受(accept)后,提案获得批准(chosen),由proposer将这个消息告知learner。这个简略的过程经过进一步细化后就形成了Paxos算法。

    在一个paxos实例中,每个提案需要有不同的编号,且编号间要存在全序关系。可以用多种方法实现这一点,例如将序数和proposer的名字拼接起来。如何做到这一点不在Paxos算法讨论的范围之内。

    如果一个没有chosen过任何proposer提案的acceptor在prepare过程中回答了一个proposer针对提案n的问题,但是在开始对n进行投票前,又接受(accept)了编号小于n的另一个提案(例如n-1),如果n-1和n具有不同的value,这个投票就会违背P2c。因此在prepare过程中,acceptor进行的回答同时也应包含承诺:不会再接受(accept)编号小于n的提案。这是对P1的加强:

    P1a:当且仅当acceptor没有回应过编号大于n的prepare请求时,acceptor接受(accept)编号为n的提案。
    

    现在已经可以提出完整的算法了。

     决议的提出与批准

    通过一个决议分为两个阶段:

    1. prepare阶段:
      1. proposer选择一个提案编号n并将prepare请求发送给acceptors中的一个多数派;
      2. acceptor收到prepare消息后,如果提案的编号大于它已经回复的所有prepare消息,则acceptor将自己上次接受的提案回复给proposer,并承诺不再回复小于n的提案;
    2. 批准阶段:
      1. 当一个proposer收到了多数acceptors对prepare的回复后,就进入批准阶段。它要向回复prepare请求的acceptors发送accept请求,包括编号n和根据P2c决定的value(如果根据P2c没有已经接受的value,那么它可以自由决定value)。
      2. 在不违背自己向其他proposer的承诺的前提下,acceptor收到accept请求后即接受这个请求。

    这个过程在任何时候中断都可以保证正确性。例如如果一个proposer发现已经有其他proposers提出了编号更高的提案,则有必要中断这个过程。因此为了优化,在上述prepare过程中,如果一个acceptor发现存在一个更高编号的提案,则需要通知proposer,提醒其中断这次提案。

     实例

    用实际的例子来更清晰地描述上述过程:

    有A1, A2, A3, A4, A5 5位议员,就税率问题进行决议。议员A1决定将税率定为10%,因此它向所有人发出一个草案。这个草案的内容是:

    现有的税率是什么?如果没有决定,则建议将其定为10%.时间:本届议会第3年3月15日;提案者:A1
    

    在最简单的情况下,没有人与其竞争;信息能及时顺利地传达到其它议员处。

    于是, A2-A5回应:

    我已收到你的提案,等待最终批准
    

    而A1在收到2份回复后就发布最终决议:

    税率已定为10%,新的提案不得再讨论本问题。
    

    这实际上退化为二阶段提交协议。

    现在我们假设在A1提出提案的同时, A5决定将税率定为20%:

    现有的税率是什么?如果没有决定,则建议将其定为20%.时间:本届议会第3年3月15日;提案者:A5
    

    草案要通过侍从送到其它议员的案头. A1的草案将由4位侍从送到A2-A5那里。现在,负责A2和A3的侍从将草案顺利送达,负责A4和A5的侍从则不上班. A5的草案则顺利的送至A4和A3手中。

    现在, A1, A2, A3收到了A1的提案; A4, A3, A5收到了A5的提案。按照协议, A1, A2, A4, A5将接受他们收到的提案,侍从将拿着

    我已收到你的提案,等待最终批准
    

    的回复回到提案者那里。

    而A3的行为将决定批准哪一个。

     情况一

    假设A1的提案先送到A3处,而A5的侍从决定放假一段时间。于是A3接受并派出了侍从. A1等到了两位侍从,加上它自己已经构成一个多数派,于是税率10%将成为决议. A1派出侍从将决议送到所有议员处:

    税率已定为10%,新的提案不得再讨论本问题。
    

    A3在很久以后收到了来自A5的提案。由于税率问题已经讨论完毕,他决定不再理会。但是他要抱怨一句:

    税率已在之前的投票中定为10%,你不要再来烦我!
    

    这个回复对A5可能有帮助,因为A5可能因为某种原因很久无法与与外界联系了。当然更可能对A5没有任何作用,因为A5可能已经从A1处获得了刚才的决议。

     情况二

    依然假设A1的提案先送到A3处,但是这次A5的侍从不是放假了,只是中途耽搁了一会。这次, A3依然会将"接受"回复给A1.但是在决议成型之前它又收到了A5的提案。这时协议有两种处理方式:

    1.如果A5的提案更早,按照传统应该由较早的提案者主持投票。现在看来两份提案的时间一样(本届议会第3年3月15日)。但是A5是个惹不起的大人物。于是A3回复:

    我已收到您的提案,等待最终批准,但是您之前有人提出将税率定为10%,请明察。
    

    于是, A1和A5都收到了足够的回复。这时关于税率问题就有两个提案在同时进行。但是A5知道之前有人提出税率为10%.于是A1和A5都会向全体议员广播:

     税率已定为10%,新的提案不得再讨论本问题。
    

    一致性得到了保证。

    2. A5是个无足轻重的小人物。这时A3不再理会他, A1不久后就会广播税率定为10%.

     情况三

    在这个情况中,我们将看见,根据提案的时间及提案者的权势决定是否应答是有意义的。在这里,时间和提案者的权势就构成了给提案编号的依据。这样的编号符合"任何两个提案之间构成偏序"的要求。

    A1和A5同样提出上述提案,这时A1可以正常联系A2和A3; A5也可以正常联系这两个人。这次A2先收到A1的提案; A3则先收到A5的提案. A5更有权势。

    在这种情况下,已经回答A1的A2发现有比A1更有权势的A5提出了税率20%的新提案,于是回复A5说:

    我已收到您的提案,等待最终批准。
    

    而回复了A5的A3发现新的提案者A1是个小人物,不予理会。

    A1没有达到多数,A5达到了,于是A5将主持投票,决议的内容是A5提出的税率20%.

    如果A3决定平等地对待每一位议员,对A1做出"你之前有人提出将税率定为20%"的回复,则将造成混乱。这种情况下A1和A5都将试图主持投票,但是这次两份提案的内容不同。

    这种情况下, A3若对A1进行回复,只能说:

    有更大的人物关注此事,请等待他做出决定。
    

    另外,在这种情况下, A4与外界失去了联系。等到他恢复联系,并需要得知税率情况时,他(在最简单的协议中)将提出一个提案:

    现有的税率是什么?如果没有决定,则建议将其定为15%.时间:本届议会第3年4月1日;提案者:A4
    

    这时,(在最简单的协议中)其他议员将会回复:

    税率已在之前的投票中定为20%,你不要再来烦我!
    

     决议的发布

    一个显而易见的方法是当acceptors批准一个value时,将这个消息发送给所有learner。但是这个方法会导致消息量过大。

    由于假设没有Byzantine failures,learners可以通过别的learners获取已经通过的决议。因此acceptors只需将批准的消息发送给指定的某一个learner,其他learners向它询问已经通过的决议。这个方法降低了消息量,但是指定learner失效将引起系统失效。

    因此acceptors需要将accept消息发送给learners的一个子集,然后由这些learners去通知所有learners。

    但是由于消息传递的不确定性,可能会没有任何learner获得了决议批准的消息。当learners需要了解决议通过情况时,可以让一个proposer重新进行一次提案。注意一个learner可能兼任proposer。

     Progress的保证

    根据上述过程当一个proposer发现存在编号更大的提案时将终止提案。这意味着提出一个编号更大的提案会终止之前的提案过程。如果两个proposer在这种情况下都转而提出一个编号更大的提案,就可能陷入活锁,违背了Progress的要求。这种情况下的解决方案是选举出一个leader,仅允许leader提出提案。但是由于消息传递的不确定性,可能有多个proposer自认为自己已经成为leader。Lamport在The Part-Time Parliament一文中描述并解决了这个问题。

     其他

    微软公司为简化的Paxos算法申请了专利[2]。但专利中公开的技术和本文所描述的不尽相同。

    谷歌公司(Google公司)在其分布式锁服务(Chubby lock)中应用了Paxos算法[3]。Chubby lock应用于大表(Bigtable),后者在谷歌公司所提供的各项服务中得到了广泛的应用[4]

        PAXOS是一种基于消息传递且具有高度容错特性的一致性算法。算法本身用语言描述极其精简:

    phase 1
    a) proposer向网络内超过半数的acceptor发送prepare消息
    b) acceptor正常情况下回复promise消息
    phase 2
    a) 在有足够多acceptor回复promise消息时,proposer发送accept消息
    b) 正常情况下acceptor回复accepted消息

    PAXOS中有三类角色Proposer、Acceptor及Learner,主要交互过程在Proposer和Acceptor之间,做成图便如下图所示:
    其中1,2,3,4代表顺序。
    以下图描述多Proposer的情况,T代表时间轴,图中仅画全一个Proposer与Acceptor的关系:

    A3在T1发出accepted给A1,然后在T2收到A5的prepare,在T3的时候A1才通知A5最终结果(税率10%)。这里会有两种情况:
    1. A5发来的N5小于A1发出去的N1,那么A3直接拒绝(reject)A5
    2. A5发来的N5大于A1发出去的N1,那么A3回复promise,但带上A1的(N1, 10%)
    最终A5也会接受10%
    上图描述,如果已经Promise一个更大的N,那么会直接Reject更小的N
    上述描述了,即使Promise了一个N,如果在未Accepted前,再收到一个更大的N,那么依旧会Reject那个即使已经Promise的N
    总流程图氪概括如下:
    PAXOS协议用于微信PaxosStore中,每分钟调用Paxos协议过程数十亿次量级。


        作为现在共识算法设计的鼻祖,以最初论文的难懂(算法本身并不复杂)出名。

    算法中将节 点分为三种类型:

    proposer:提出一个提案,等待大家批准为结案。往往是客户端担任该角色;

    acceptor:负责对提案进行投票。往往是服务端担任该角色;

    learner:被告知结案结果,并与之统一,不参与投票过程。可能为客户端或服务端。

    并且,算法需要满足 safety 和 liveness 两方面的约束要求(实际上这两个基础属性是大部分 分布式算法都该考虑的):

    safety:保证决议结果是对的,无歧义的,不会出现错误情况。

        决议(value)只有在被 proposers 提出的 proposal 才能被最终批准;

        在一次执行实例中,只批准(chosen)一个最终决议,意味着多数接受(accept) 的结果能成为决议;

    liveness:保证决议过程能在有限时间内完成。

        决议总会产生,并且 learners 能获得被批准(chosen)的决议。

    基本过程包括 proposer 提出提案,先争取大多数 acceptor 的支持,超过一半支持时,则发送 结案结果给所有人进行确认。

    一个潜在的问题是 proposer 在此过程中出现故障,可以通过超 时机制来解决。

    极为凑巧的情况下,每次新的一轮提案的 proposer 都恰好故障,系统则永远 无法达成一致(概率很小)。

    Paxos 能保证在超过1/2的正常节点存在时,系统能达成共识。

    展开全文
  • Paxos:Paxos的实现-源码

    2021-03-08 07:45:03
    Paxos Paxos的实现
  • Paxos算法

    千次阅读 2019-06-16 16:58:36
    Paxos

    分布式系统中只存在“一种”一致性算法,那就是Paxos算法。前面提到的一致性看起来很容易实现,但是这都是建立在无故障或者允许无限等待或恢复的基础上。比如2PC就是无限等待协议,投票需要所有人都在。显然,这种方式在容错方面表现不好。Paxos是容错的分布式一致性算法,尽管节点可能会出错,网络会发生故障或者延迟,但所有节点都会同意相同的值

    一致性的要求

    正确性:满足一致性的定义;
    容错:少部分节点挂了不影响整个过程;
    可停止。
    但是Paxos算法只能保证前两项。Paxos的目标是让所有的接受者同意提案

    Paxos中出现的角色

    客户端:发起请求
    提议者(Proposer):接收请求并执行协议,领导者(Leader)为选举出来的协调者;
    接受者(Acceptor):记住协议的状态,法定人数(Quorum)为任意大部分接受者的集合;
    学习者(Learner):当一致意见抵达时,学习者执行请求或者发送回复给客户端。
    粗略的过程:一个提议者决定成为一个leader,leader提出一个值并让大多数接受者接受。leader宣布结果或者重新再提议。
    每个节点同时为一个提议者,一个接受者,一个学习者。

    详细流程

    阶段0:客户端发送请求给一个提议者;
    阶段1a:指挥者创建提议N,发送给法定人数(N比该提议者使用的任何之前提议的编号都要大);
    在这里插入图片描述
    阶段1b:接受者收到提议,如果提议N比之前提议大,那么回复leader过去提议最高的编号和值,并承诺忽视所有小于N的提议;如果提议N比之前的提议小,直接忽略掉,提议被拒绝。
    在这里插入图片描述
    阶段2a:leader如果收到了足够的允诺,则设定提议的值为V,V可以是决定好的也可以是最新的值,并发送带有N和V的接收请求给法定人数。
    在这里插入图片描述
    阶段2b:对于接受者,如果提议仍然保留,注册V值,发送已接收信息给提议者和学习者;否则,忽略该请求。
    在这里插入图片描述
    阶段3:学习者回复客户端或对请求进行操作。

    展开全文
  • paxos:Paxos的实现-源码

    2021-06-14 17:18:07
    帕克索斯 使用 Akka 实现单实例 Paxos

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,437
精华内容 2,174
关键字:

paxos