聊聊分布式一致性算法协议 Paxos

网站建设4年前发布
62 0 0

Google的粗粒度锁服务Chubby的设计开发者Burrows曾经说过:所有一致性协议本质上要么是Paxos要么是其变体。,网上有很多讲解Paxos算法的文章,但是质量层次不齐。今天笔者带大家深入聊一下Paxos。,Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。,Paxos算法是Lamport宗师提出的一种基于消息传递的分布式一致性算法,使其获得2013年图灵奖。,自Paxos问世以来就持续垄断了分布式一致性算法,Paxos这个名词几乎等同于分布式一致性。,Google的很多大型分布式系统都采用了Paxos算法来解决分布式一致性问题,如Chubby、Megastore以及Spanner等。开源的ZooKeeper,以及MySQL 5.7推出的用来取代传统的主从复制的MySQL Group Replication等纷纷采用Paxos算法解决分布式一致性问题。,但是它也有两个明显的缺点:,在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括消息的延迟、丢失、重复、乱序,还有网络分区)等情况。Paxos算法需要解决的问题就是如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。,这里某个数据的值并不只是狭义上的某个数,它可以是一条日志,也可以是一条命令(command)。根据应用场景不同,某个数据的值有不同的含义。,在Paxos算法中,有三种角色:,需要注意的是,在具体的算法实现过程中,并不是一个进程只能担任其中一种角色,它有可能会同时充当多个。比如一个进程既是Proposer又是Acceptor还是Learner。,还有一个很重要的概念叫提案(Proposal)。最终要达成一致的value就在提案里。,这个提案包括什么呢?是仅仅包括一个信息数值吗?到底是如何咱们继续向下阅读,目前咱们先认为仅仅是一个普普通通的value。,Paxos算法过程和我国的立法过程是极其相似的(法律案的提出、法律案的审议、法律案的表决、法律的公布四个阶段),所谓的提案就是新颁布法律。,Proposer (提案者)可以提出(propose)提案;Accoptor可以接受(accept)提案;如果某个提案被选定(chosen),那么该提案里的value就被选定了。,回到刚刚说的『对某个数据的值达成一致』,指的是Proposer、Acceptor、Learner都认为同一个value被选定(chosen)。那么,Proposer、Acceptor、Learner分别在什么情况下才能认为某个value被选定呢?,假设有一组可以提出(propose)value的进程集合(提案者团队),一个一致性算法需要保证提出的这么多value中,仅仅只有一个相同的value被选定(chosen)。也就是说要么没有value被提出,只要提出了value并且被选定,那么大家最终学习到的value必须是一致的。对于一致性算法,安全性(safaty)要求如下:,Paxos的目标:保证最终有一个value会被选定,当value被选定后,进程最终也能获取到被选定的value。,俗话说的好,哪里有需求,哪里就会出现糟糕的问题。如果假设不同角色之间可以通过发送消息来进行通信,那么:,以上都是可能会遇到的问题,要怎么解决???,假设只有一个Acceptor(可以有多个Proposer),只要Acceptor接受它收到的第一个提案,则该提案被选定,该提案里的value就是被选定的value。这样就保证只有一个value会被选定。,但是,如果这个唯一的Acceptor宕机了,那么整个系统就无法工作了!,因此,一个Acceptor是不可行的,必须要有多个Acceptor!,当有多个Acceptor的时候,如何保证在多个Proposer和多个Acceptor的情况下选定一个value呢?,大家可以自己先进行思考。,首先,我们的最终目标是无论有多少Proposer提出提案,有且仅有一个value被选定。,那么,我们可以先定义一个约束:,但是,这样又会出现其它的问题:如果每个Proposer所提出的提案value是不同的,并且将提案发送给不同的Acceptor。根据P1约束,每个Acceptor都接受它收到的第一个提案,就会出现不同value被选定的情况,出现了不一致。,刚刚是因为『一个提案只要被一个Acceptor接受,则该提案的value就被选定了』才导致了出现上面不一致的问题。因此,我们需要加一个规定:,一个提案被半数以上接受,说明『一个Acceptor必须能够接受不止一个提案!』,不然可能导致最终没有value被选定。比如上图的情况。v1、v2、v3都没有被选定,因为它们都只被一个Acceptor的接受,并没有被超过半数以上的Acceptor接受。,最开始将【提案 = value】已经无法满足现在的需求,因为当一个Proposer发送多个提案到一个Acceptor的时候,需要使用一个编号来区分被提出的顺序。现在【提案=提案编号+value】。,虽然允许多个提案被选定,但必须保证所有被选定的提案都具有相同的value值。否则又会出现不一致。,一个提案只有被Acceptor接受才可能被选定,因此我们可以把P2约束改写成对Acceptor接受的提案的约束P2a。,只要满足了P2a,就能满足P2。,但是,考虑如下的情况:以立法过程为背景,假设总的有5个人大代表(Acceptor)。,人民法院(Proposer2)提出[M1,V1]的提案,人大代表2-5号(半数以上)均接受了该提案,于是对于人大代表2-5号和人民法院来讲,它们都认为V1提案是被选定的。此时,人大代表1在办完其它事务之后也参与到其中(之前人大代表1没有收到过任何提案),此时最高人民检察院(另一个提案者Proposer1)向人大代表1发送了[M2,V2]的提案(V2≠V1且M2>M1),对于人大代表1来讲,这是它收到的第一个提案。根据P1(一个Acceptor必须接受它收到的第一个提案。),人大代表1必须接受该提案!同时人大代表1认为V2被选定。这就出现了两个问题:,所以,我们要对P2a约束进行加强!,P2a是对Acceptor接受的提案约束,但其实提案是Proposer提出来的,所有我们可以对Proposer提出的提案进行约束。得到P2b:,那么,如何确保在某个value为v的提案被选定后,Proposer提出的编号更高的提案的value都是v呢?,只要满足P2c即可:,为了满足P2b,这里有个比较重要的思想:Proposer生成提案之前,应该先去『学习』已经被选定或者可能被选定的value,然后以该value作为自己提出的提案的value。如果没有value被选定,Proposer才可以自己决定value的值。这样才能达成一致。这个学习的阶段是通过一个『Prepare请求』实现的。,于是我们得到了如下的提案生成算法:,(1) Proposer选择一个新的提案编号N,然后向某个Acceptor集合(半数以上)发送请求,要求该集合中的每个Acceptor做出如下响应(response):,我们将该请求称为编号为N的Prepare请求。,(2) 如果Proposer收到了半数以上的Acceptor的响应,那么它就可以生成编号为N,Value为V的提案[N,V]。这里的V是所有的响应中编号最大的提案的Value。如果所有的响应中都没有提案,那 么此时V就可以由Proposer自己选择(一般为当前提案)。,生成提案后,Proposer将该提案发送给半数以上的Acceptor集合,并期望这些Acceptor能接受该提案。我们称该请求为Accept请求。(注意:此时接受Accept请求的Acceptor集合不一定是之前响应Prepare请求的Acceptor集合),Acceptor可以忽略任何请求(包括Prepare请求和Accept请求)而不用担心破坏算法的安全性。因此,我们这里要讨论的是什么时候Acceptor可以响应一个请求。,我们对Acceptor接受提案给出如下约束:,如果Acceptor收到一个编号为N的Prepare请求,在此之前它已经响应过编号大于N的Prepare请求。根据P1a,该Acceptor不可能接受编号为N的提案。因此,该Acceptor可以忽略编号为N的Prepare请求。当然,也可以回复一个error,让Proposer尽早知道自己的提案不会被接受。,因此,一个Acceptor只需记住:,经过上面的推导,我们总结下Paxos算法的流程。,Paxos算法分为两个阶段。具体如下:,阶段一:,阶段二:,Learner学习(获取)被选定的value有如下三种方案:,方案一:,Acceptor接受到一个提案,就将该提案发送给所有Learners.,方案二,Acceptor接受一个提案,就将提案发送给主Learner,主Learner再通知其它Learner,方案三,Acceptor接受一个提案,就将提案发送给Learner团,Learner团再通知其它Learner,通过选取主Proposer,就可以保证Paxos算法的活性。通过选取主Proposer,并规定只有主Proposer才能提出议案。这样一来只要主Proposer和过半的Acceptor能够正常进行网络通信,那么但凡主Proposer提出一个编号更高的提案,该提案终将会被批准,这样通过选择一个主Proposer,整套Paxos算法就能够保持活性。至此,我们得到一个既能保证安全性,又能保证活性的分布式一致性算法——Paxos算法。,到此,我们针对Paxos算法是什么、它的特性以及算法的具体推导过程做了详细的阐述。Paxos算法是现在很多一致性算法的变体,非常值得我们学习。

© 版权声明

相关文章