Leslie Lamport大神在《Paxos make simple》一文中说到:

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

确实,Paxos算法简单来看,就是几轮消息交流的事。但是,真正理解Paxos算法的设计思路以及设计选择,却并非易事。

本文结合个人理解,对《The Part-Time Parliament》一文进行翻译,以帮助大家更好地理解Paxos。(纯原创,手码。转载请注明出处)


                                               兼职议会

1. 问题

1.1. Paxos小岛

19世纪初,位于爱琴海的Paxos小岛是一个繁荣的商业中心。繁荣的商业导致政治复杂化,岛上的居民用议会形式的政府取代了之前采用的民主。但是谋生要比公民责任重要,岛上没有人愿意终生献身于议会。在议员时不时地离开议会厅的情况下,如何保证Paxos岛上的议会发挥作用?

兼职议会处理的问题与今天容错分布式系统中的问题明显相关,议员对应于进程,离开议会厅对应于故障。计算机学家或许对Paxos岛上的解决方案有兴趣。本文将展示Paxos议会协议的简短历史,同时也包括它和分布式系统相关性的一个简短的讨论。

Paxos文明由于异邦入侵被毁灭,考古学家最近才开始研究它的历史。因此,关于Paxos议会的了解是不完整的。尽管知道基本的Paxos协议,对于许多细节我们并不知道。这些细节令人感兴趣,本文将自由地推测Paxos居民可能做了什么。

1.2. 需求

议会主要的任务是决定本地的法律,法律由议会通过的一系列法令组成。现代议会会雇佣秘书来记录行为,但在Paxos,没有人愿意在整个议会期间留在议会厅当秘书。但在Paxos议会中,每个议员有一个“分类账”,议员会在分类账中按顺序记下通过的法令。例如,议员Λ˘ινχ如果了解到议会通过的第155条法令是将橄榄税设置为每吨3德拉马克(古希腊货币单位),则她会在分类账中记录下:

155:橄榄税是每吨3德拉克马

分类账用永不褪色的墨水书写,并且分类账中的内容不会改变。

Paxos议会协议的第一个需求就是分类账需要保证一致性,即:没有两个分类账包含了矛盾的信息。如果ΦισΦρ在分类账中有以下条目:

132:灯只能使用橄榄油

那么,所有议员的分类账不可以包括一个不一样的132法令条目。然而,如果存在议员不知道132法令的话,那么他的分类账中可以没有132法令条目。

分类账的一致性可以通过保持所有分类账空白来简单地实现,所以只实现分类账的一致性是不够的,还需保证最终能通过法令并且法令被纪录在分类账上。在现代议会中,议员的分歧会阻碍法令的通过。在Paxos小岛,并不会这样,这里的人相互信任。Paxos议员乐于通过任何被提出法令。然而,他们时不时地离开和加入议会厅产生了一个问题。如果一组议员通过了以下法令:

37:禁止在寺庙墙壁上画画

然后,这组议员由于要参加宴会离开了议会厅,这时另一组议员进入了议会厅,并不知道刚刚通过的法令,并且通过了冲突的法令:

37:艺术表达自由得到保障

这样,分类账的一致性就会丢失。

除非足够多的议员待在议会厅足够长的时间,否则,进展(有法令通过)不能被保证。因为Paxos岛上的议员不愿意缩短他们外出活动的时间,所以确保任何法令被通过是不可能的。然而,议员乐于保证,在议会厅的时候,他们以及他们的助手会及时处理所有的议会问题。这个保证使得Paxos居民可以设计一个满足下列进展条件的议会协议:

如果大多数的议员待在议会厅,并且没有人进入或者离开议会厅长达足够长的时间,那么,议会厅里的议员提出的任何法令都会被通过,并且每个通过的法令都会被记录在议会厅里每个议员的分类账中。

1.3 假设

只有给议员提供必要的资源,议会协议的需求才能被实现。每个议员会拥有一个记录法令的分类账,一支钢笔,以及永不褪色的墨水。如果议员离开议会厅,可能会忘记他们在议会里做了什么,所以他们会在分类账后面记下笔记来提醒自己重要的议会任务。分类账中的法令永远不会改变,但是笔记可以被划掉。实现进展条件需要议员可以知道时间的流逝,所以他们会收到一个简单的滴漏计时器。

议员时刻携带他们的分类账,总是能查分类账上的法令以及没有被划掉的笔记。分类账用最好的羊皮纸制作,只用来记下最重要的笔记。议员会在一张纸上写下其他的笔记,当他离开议会厅时,这些纸可能被丢失。

议会厅里的音响很差,不可能在里面发表演说,所以议员之间的交流只能通过信使,并且议会有足够多的经费雇佣所需的信使。信使不会混淆消息,但是可能会忘记他已经传送了一条消息,会再次传送该条消息。就像他们所服务的议员一样,信使也只能花费部分的时间在议会中。在传送一条消息之前,信使可能会离开议会厅去做生意,或许去度6个月的假。或许信使会永久离开,信息将永远不能被送达。

尽管议员和信使能随时进入或者离开议会厅,但当他们在议会厅时,他们会全神贯注在议会事情上。当信使在议会厅的时候,他们会及时传送消息。当议员在议会厅时,他们会对收到的消息立即响应。

Paxos官方记录表明,议员和信使都是诚实的并严格服从议会协议。大多数的学者认为这只是一个宣传,为了让Paxos在道德上比邻国优越。不诚实的行为,尽管很少,但也存在。然而,因为在官方的文件中没有提及不诚实的行为,我们并不知道议会如何处理不诚实的议员或者信使。在3.3.5中,我们会讨论发现的证据。

2. 单法令议会

Paxos议会从早期的每19年举行一次的牧师祭祀会发展而来,牧师祭祀会会产生单个标志性的法令。数百年来,会议需要所有牧师都在场以选择法令。但随着商业繁荣,在会议举行期间,牧师开始时不时地离开去做生意。最后,牧师祭祀会失败了,会议结束,没有产生选中的法令。为了防止这次灾难的重复,Paxos的宗教领导者要求数学家重新制定一个协议来选择一个法令。协议的需求和假设在本质上和第3节多法令议会协议是一样的,除了只产生单个法令,而不是一系列法令,也就是:一个分类账最多只有一个法令。这部分描述单法令议会协议,多法令议会协议将在第三节描述。

数学家从几个步骤开始,派生出单法令议会协议。首先,他们证实了一个结论,结论表明:满足特定约束的协议将会保证一致性以及进展需求。一个初步的协议直接从这些约束中产生。在初步协议上加一些限制,随后产生了基本协议,基本协议只保证一致性,不满足进展需求。完整的会议协议满足一致性以及进展需求,通过在基本协议的基础上产生。

2.1部分描述了数学结论,2.2-2.4部分通俗地描述了协议。基本协议的正式描述和正确性证明在附录中描述。

2.1 数学结论

通过一系列含有编号的投票,议会最终可以选中一个法令。一次投票是针对单个法令的全体投票。在每次投票中,牧师只有投票和不投票的选择。和一次投票相关的是一个牧师群体(集合),称为法定人数。当且仅当法定人数中的每个牧师都为法令投票,才可以说一次投票是成功的。正式点说,一次投票B包括下列四个部分(除非另有说明,牧师集合是指有限集):

B(dec):一个法令(被投票的对象);

B(qrm):一个非空的牧师集合(投票的法定人数);

B(vot):投票牧师的集合(为法令投票的牧师集合);

B(bal):投票编号。

当且仅当B(qrm)B(vot),才能说一次投票B是成功的,所以一次成功的投票就是每个法定人数都投票了。

投票的编号从一组无界有序的数集中选择。如果B1(bal)>B(bal),那么投票B1晚于投票B。然而,这并不表示投票被执行的顺序,较晚的投票可能在较早投票之前进行。

Paxos的数学家在投票集合b上定义了三种条件,并且表明如果进行的投票集合满足这些条件,一致性将会得到保证,进展也会有可能。前两个条件很简单,他们可以被描述如下:

B1(b):b中的每次投票都有一个独一无二的投票编号

B2(b):b中的任意两次投票的法定人数的交集不为空,即:任意两次投票的法定人数至少有一个共同的牧师。

第三个条件要复杂一些,一个手稿纪录了关于第三个条件的陈述,这是个令人困惑的陈述:

B3(b):对于b中的每次投票B,如果B法定人数中的牧师在集合b早期的投票中进行了投票,那么,B的法令等于这些早期投票中最晚投票的法令。

条件B3(b)的解释在手稿中以图1的形式给出,图1中的会议包含了5个牧师A, B, Γ, ∆, E,投票集合b包括5次投票。集合b包含的5次投票中,每次投票的投票者集合都是法定人数的子集,法定人数中牧师的名字被放在封闭的箱子里。例如,投票编号14的法令为a,法定人数包括3个牧师,其中两个牧师进行了投票。条件B3(b)的形式是“对于b中的每次投票B,如果……”,“如果.…..”是投票B的条件。图1中5次投票的条件如下:

图1  集合b包括5次投票,满足条件B1(b)-B3(b)

5:编号为5的投票中四个法定人数没有牧师在之前的投票中进行过投票,所以投票5的条件为真。

14:编号为14的投票中,法定人数中只有∆在编号为2的投票中进行了投票。所以B3(b)要求编号为14的投票的法令一定要等于编号为2的投票法令。

27:(这是一次成功的投票)编号为27的投票的法定人数含有A, Γ和∆。牧师A在早期的投票中没有进行投票,牧师Γ只在编号为5的投票中进行了投票,牧师∆只在编号为2的投票中进行了投票。这两次投票中比较晚的一次是编号为5的投票,因此条件B3(b)要求编号为27的投票的法令一定要等于编号为5的投票的法令。

29:编号为29的投票的法定人数的成员有B, Γ和∆。牧师B只在编号为14的投票中进行了投票,牧师Γ在编号为5和编号为27的投票中进行了投票,牧师∆在编号为2和编号为27的投票中进行了投票。这些投票中较晚的一次投票是编号为27的投票,因此B3(b)要求编号为29的投票的法令一定要等于编号为27的投票的法令。

较为正式地描述条件B1(b)-B3(b)需要更多的数学符号。选票v包含三个部分:一个牧师v(pst),一个投票编号v(bal)以及一个法令v(dec)。它表示牧师v(pst)在投票编号为v(bal)的投票中为法令v(dec)进行了投票。Paxos居民也定义了null选票,null选票的v(bal)=负无穷,v(dec)=BLANK,其中BLANK不是法令,对于任何投票编号b,满足负无穷<b<正无穷。对于任何牧师p,定义null(p)是v(pst)=p的null选票。

Paxos的数学家在所有的选票集合上定义了全局顺序,但是定义部分的手稿有部分丢失了。残留的碎片显示,对于选票v以及v’,如果v(bal)<v’(bal),那么v<v’。但并不清楚当v(bal)=v’(bal)时,v和v’的相对顺序如何定义。

对于任何投票集合b,选票集合Votes(b)表示所有的选票v,对于投票Bb,v(pst)B(vot), v(bal)=B(bal), v(dec)=B(dec)。如果p是一个牧师,ba或者是一个投票编号或者是正负无穷,那么MaxVote(ba, p, b)被定义为是在选票集合Votes(b)中,由p所投的v(bal)<ba的最大选票v;如果没有这样的选票的话,MaxVote(ba, p, b)为null(p)。既然null(p)比p所投的任何选票都小,那么MaxVote(ba,p, b)表示在下列集合中的最大的选票:

{ vVotes(b): ( v(pst)=p )( v(bal)<ba ) }  { null(p) }

对于任何非空的牧师集合Q,MaxVote(ba, Q, b)表示对于Q中的p,所有选票MaxVote(ba, p, b)中最大的选票。

条件B1(b)-B3(b)可以正式描述为如下所示:

B1(b) : B, B1b: BB1 B(bal) B1(bal)

B2(b): B, B1b: B(qrm)B1(qrm)

B3(b): Bb: MaxVote(ba,B(qrm),b)(bal)负无穷B(dec)=MaxVote(ba,B(qrm),b)(dec)

尽管MaxVote的定义取决于选票的顺序,B1(b)表明MaxVote(ba,Q,b)(dec)和具有相同投票编号的选票顺序无关。

为了表明这些条件确保一致性,Paxos居民首先表明条件B1(b)-B3(b)确保如果b中的一次投票B是成功的,那么b中任何随后的投票都和B有相同的法令。

引理 如果B1(b),B2(b),B3(b)满足,那么对于b中的任何B, B’都有:

( ( B(qrm)  B(vot) )  ( B’(bal) > B(bal) ) )B’(dec) = B(dec)

引理证明(略,参见原文)

利用引理,很容易发现,如果B1(b)-B3(b)满足,那么任何两次成功的投票具有相同的法令。

定理1 如果B1(b),B2(b)以及B3(b)满足,那么对于b中的任何B和B’,有:

(( B(qrm)  B(vot) )( B’(qrm)  B’(vot) ))( B’(dec) = B(dec) )

定理1证明(略,参见原文)

Paxos居民接着证明了一个定理:如果有足够多的牧师在议会厅,那么在满足条件B1(b)-B3(b)的情况下,进行一次成功的投票是有可能的。尽管这不能确保进展,但它至少表明基于条件B1(b)-B3(b)的投票协议不会死锁。

定理2 假设ba为一个投票编号,Q为一组牧师集合,对于所有的Bb,ba>B(bal)并且QB(qrm)。如果条件B1(b)-B3(b)满足,那么存在一次投票B’,B’(bal)=ba并且B’(qrm)=B’(vot)=Q,使得条件B1(b{B’})-B3((b{B’})满足。

定理2证明(略,参见原文)

2.2 初步协议

Paxos居民从条件B1(b)-B3(b)保持为真的需求派生出了初步协议,b是已经进行或者正在进行的所有投票的集合。协议指出了集合b是如何变化的,但从未明确计算过集合b。Paxos居民认为b只能由神观察到,凡人可能永远不知道。

每次投票由一个牧师发起,牧师选择投票编号,法令以及法定人数。法定人数中的每个牧师决定是否在本次投票中进行投票。发起者如何选择投票的编号,法令和法定人数,以及法定人数中的牧师决定是否进行投票的规则由B1(b)-B3(b)的需求决定。

为了满足B1,每次投票必须有一个独一无二的编号。牧师通过记住(在分类账上做笔记)先前提出的投票,可以容易地避免在两次不同的投票中提出相同的编号。为了避免不同的牧师用相同的编号提出投票,投票编号集合根据牧师的不同进行分区。虽然不知道这是如何实现的,但是一种显而易见的方法是让一个投票编号由一个整数和一个牧师对组成,使用字典序。如果在Paxos的字母表里,Γ在Λ之前出现,那么:

(13, Γρα ˘ ι) < (13, Λινσ ˘ ι) < (15, Γρα ˘ ι)

任何情况下,有一个没有边界的投票编号集合供每个牧师使用。

为了满足条件B2,每次投票的法定人数包含牧师中的µαδζ∂ωριτ˘ισΦτ。一开始,µαδζ∂ωριτ˘ισΦτ表示大多数牧师。随后,观察到胖的牧师很少移动,相比瘦的牧师,在议会厅待更多的时间。所以,µαδζ∂ωριτ˘ισΦτ表示全部体重超过所有牧师总体重一半的牧师集合,而不是简单的大多数牧师。一些瘦的牧师抱怨这不公平,用基于牧师出勤记录的象征性体重来替代真实的体重。选择µαδζ∂ωριτ˘ισΦτ的要求是任何两个包括µαδζ∂ωριτ˘ισΦτ的牧师集合至少有一个共同牧师。为了满足条件B2,牧师初始化投票B时,将B(qrm)定义为一个大多数集合。

条件B3要求,如果MaxVote(ba,Q,b)(dec)不为BLANK,那么法定人数为Q,投票编号为ba的法令一定为MaxVote(ba,Q,b)(dec)。如果MaxVote(ba,Q,b)(dec)等于BLANK,那么投票可以选择任何法令。为了满足B3(b),在初始化法定人数为Q投票编号为ba的投票之前,一个牧师p必须知道MaxVote(ba,Q,b)(dec)。因此,p必须找到Q中每个牧师q的MaxVote(ba, q, b)。MaxVote(ba, q, b)表示在q投的所有的选票中,投票编号低于ba的最大投票编号的选票;如果q在投票编号低于ba的投票中没有进行任何投票,那么MaxVote(ba, q, b)为null(q)。

牧师p通过信息交换从q那获取MaxVote(ba, q, b)。因此,初步协议中p发起一次投票的前两步为:

(1) 牧师p选择一个新的投票编号ba,并且发送一个NextBallot(ba)消息给某个牧师集合。

(2) 牧师q收到NextBallot(ba)消息之后,发送一个LastVote(ba,v)消息给p作为响应。v是q投出的编号比ba小的最大投票编号的选票,如果q没有在任何比ba小的投票编号的投票中没有进行过投票,那么v为null选票null(q)

牧师q需要利用分类账后面的笔记,回忆他之前所投的选票。

q发送的LastVote(ba,v)消息中,v等于MaxVote(ba, q, b)。但如果新的投票被初始化,牧师投出选票,那么投票集合b会改变。既然牧师p在选择法令的时候,打算将v作为MaxVote(ba, q, b)的值,那么为了保证条件B3(b)满足,在q发送LastVote(ba,v)消息之后,保证MaxVote(ba, q, b)不改变是十分必要的。为了防止MaxVote(ba, q, b)改变,q不能在投票编号在v(bal)和ba之间的投票中进行投票。通过发送LastVote(ba,v)消息,q承诺不会进行这样的投票。(为了保证承诺,q需要在分类账上纪录必要的信息)

初步协议(由牧师p在第一步开始)接下来的两步如下:

(3) 在收到某个大多数集合Q中的所有牧师发送的LastVote(ba,v)消息之后,牧师p使用投票编号b,法定人数Q以及法令d初始化一次新的投票,d满足条件B3。然后p将这次投票记在他分类账的背面,并且给Q中的每个牧师发送一个BeginBallot(ba, d)消息。

(4) 在收到BeginBallot(ba, d)消息之后,牧师q决定是否在投票编号为ba的投票中进行投票。(如果投票会违反他在其他投票中发送LastVote(b’, v’)信息时所做的承诺,他将不会投票。)如果q决定进行投票,他会发送一个Voted(ba, q)消息给p,并且在分类账的背面纪录下此次选票。

步骤(3)的执行意味着在b中加入了投票B,B(bal) = ba, B(qrm) = Q, B(vot) = (在这次投票中还没有人进行了投票),B(dec) = d。在步骤(4),如果牧师q决定在这次投票中进行投票,那么执行步骤4就是通过将q加入B(vot)中来改变投票集合b。

即使投票不会违反之前所做的承诺,牧师在步骤(4)中也可以不进行投票。事实上,在协议中的所有步骤都是可选的。例如,牧师q可以忽略NextBallot(b)消息,不执行步骤2。牧师响应的失败可能会妨碍进展,但是不会造成任何不一致性,因为不会使条件B1(b)-B3(b)不满足。既然没有收到消息的唯一影响就是妨碍一个行为发生,那么信息丢失也不会造成不一致性。因此,即使牧师离开会议厅或者信息丢失,协议也能保证一致性。

重复收到一个信息可能使一个行为被重复执行。除了在步骤(3),执行多次行为不产生影响。例如,在步骤4发送几个Voted(ba, q)消息和发送一个消息有相同的效果。当执行步骤3时,我们使用分类账后面的笔记来防止步骤3被重复执行。因此,即使信使传送同一消息几次,一致性条件仍能保持。

步骤(1)-(4)描述了初始化一次投票以及对该投票进行投票的完整协议。剩下的就是决定投票的结果,并当法令被选中时,宣布出来。当且仅当法定人数中的每个牧师都投票了,才能说一次投票是成功的。一次成功投票的法令就是会议选中的法令。剩下的协议如下:

(5) 如果p从Q(投票编号为ba的投票的法定人数)中的每个牧师q那都收到了一个Voted(ba, q)消息,那么他将d(投票的法令)写入他的分类账并给每个牧师发送Success(d)信息。

(6) 在收到Success(d)信息之后,牧师在他的分类账中写入法令d。

步骤(1)-(6)描述了如何进行单次投票。初步协议允许任何牧师在任何时间初始化一次新的投票。每一步都满足条件B1(b)-B3(b),所以整个协议也满足这些条件。既然只有在投票成功时,牧师才将法令写入分类账中,定理1意味着牧师的分类账是一致的。初步协议没有处理进展问题。

在步骤(3)中,如果条件B3决定法令d,那么有可能法令已经写入某个牧师的分类账中。该牧师不需要在法定人数Q中,他可能已经离开了议会厅。因此,如果步骤3在选择d上允许任何更大的自由,一致性将不能得到保证。

2.3 基本协议

在初步协议中,牧师必须要纪录:(i)他初始化的投票的编号;(ii)他投的每个选票;(iii)已经发送的每个LastVote信息。对于忙碌的牧师来说,追踪所有的消息是很困难的。Paxos居民因此通过限制初步协议得到了更具有实际意义的基本协议,在基本协议中,每个牧师p只需在他分类账的背面纪录下列信息:

lastTried[p] :p尝试发起的最后一次投票的投票编号;如果没有,为负无穷。

prevVote[p] :p在他所投的最大编号的投票中,投出的选票;如果没有投过票,为负无穷。

nextBal[p] :p发送的LastVote(ba,v)信息中,最大的ba;如果他还没有发送LastVote信息,为负无穷。

初步协议的步骤(1)-(6)描述了牧师p如何发起一次投票。初步协议允许p并发执行任意数量的投票。在基本协议中,p一次只能执行一次投票——投票编号为lastTried[p]。在p初始化这次投票之后,他会忽视之前初始化的投票的有关信息。牧师p将所有有关投票编号为lastTried[p]的投票的进展信息写在一张纸上。如果这张纸丢了,他将停止执行这次投票。

在初步协议中,牧师q发送LastVote(ba,v)信息表示他的承诺:不在投票编号为v(bal)和ba之间的投票中进行投票。在基本协议中,它表示一个更强的承诺——不在投票编号小于ba的投票中进行投票。这个更强的承诺或许使他不能在基本协议的第(4)步进行投票,但是在初步协议中是可以投票的。然而,既然初步协议总是给p不进行投票的自由,基本协议不需要他做任何初步协议不允许的事。

初步协议的(1)-(6)步变成了如下所示的基本协议的(1)-(6)步:(p进行一次投票所需的所有信息,除了lastTried[p],prevVote[p]和nextBal[p],都记在一张纸上)

(1) 牧师p选择一个比lastTried[p]大的新的投票编号ba,将lastTried[p]设置为ba,并且给某个牧师集合发送NextBallot(ba)消息。

(2) 牧师q从p处收到NextBallot(ba)消息并且ba>nextBal[q]时,q将nextBal[q]设置为ba,并且给p发送LastVote(ba, v)消息,v等于prevVote[q]。(如果banextBal[q],那么就忽略NextBallot(ba)消息)

(3) 在从某个大多数集合Q中的每个牧师那都收到LastVote(ba, v)(ba= lastTried[p])消息之后,牧师p初始化一次新投票,投票编号为ba,法定人数为Q,法令为d,d的选择满足条件B3。p给Q中所有牧师接着发送BeginBallot(ba, d)消息。

(4) 在牧师q收到BeginBallot(ba, d)消息并且ba= nextBal[q],q在投票编号为ba的投票中投出选票,将prevVote[q]设置为此选票,并且给p发送一个Voted(ba, q)消息。(如果banextBal[q],那么就忽略BeginBallot(ba, d)消息)

(5) 如果p从Q(投票编号为ba的投票中的法定人数)中的每个牧师q那都收到了Voted(ba, q)消息,并且ba = lastTried[p],那么p将d(投票的法令)写入分类账中并给每个牧师发送Success(d)消息。

(6) 在收到Success(d)消息之后,牧师在分类账中记下法令d。

基本协议是初步协议的限制版本,意味着基本协议允许的每个行为在初步协议中都被允许。既然初步协议满足一致性条件,基本协议也满足一致性条件。就像初步协议,基本协议不需要采取任何行为,所以它不解决进展问题。

从B1-B3中派生出基本协议,所以很明显满足一致性条件。然而,一些类似“很明显”的古代智慧有时是错的,多疑的Paxos公民需要一个更严谨的证据。Paxos数学家将协议满足一致性条件的证明放在了附录中。

2.4 完整的会议协议

基本协议满足了一致性,但是并不能确保进程。因为它只描述了牧师可能做什么,并没有要求一定做什么。完整的会议协议和基本协议一样包括进行一次投票同样的6个步骤。为了帮助实现进展,完整的协议包括明显的附加要求——牧师尽快执行协议的2-6步。然而,为了满足进展需求,必须要有某个牧师执行步骤1,发起一次投票。完整的会议协议关键在于决定牧师应该什么时候发起一次投票。

不发起投票当然会妨碍进展。然而,发起太多投票也会妨碍进展。如果ba比任何其他的投票编号都大,那么在步骤(2)中牧师q接收NextBallot(ba)消息会引出一个承诺,阻止他在步骤(4)中为之前发起的投票进行投票。因此,新投票的初始化可能会阻止之前发起的投票成功。如果在之前的投票有机会成功之前,用不断增加的投票编号持续发起新投票,将会导致不能取得进展。

实现进展需要新投票被初始化直到有一次投票成功,但是新投票不要经常被初始化。为了发展完整的协议,Paxos居民首先得知道信使传送消息,牧师进行响应所需的时间。他们得出不离开会议厅的信使总能在4分钟之内传达一个消息,会议厅的牧师总能在收到消息的7分钟之内进行响应。因此,如果p发送一个消息给q,q发送响应给p时,p和q都在会议厅内,那么在没有信使离开会议厅的情况下,p将在22分钟内收到这个响应。(牧师p在7分钟之内发送信息,q在4分钟之内收到信息,在7分钟之内做出响应,响应将在4分钟之内到达p处。)

假定只有单个牧师p正在发起投票,并且他通过在协议的第(1)步给每个牧师发送消息来发起投票。如果p在大多数牧师都在会议厅的时候发起投票,那么他可以在发起投票的22分钟之内开始执行步骤3,在另外22分钟之内执行步骤5。如果他不能在这些时间内执行这些步骤,那么或者在p发起投票之后,有牧师或信使离开了会议厅或者另一个牧师之前已经发起了一个更大编号的投票(在p成为发起投票的唯一牧师之前)。为了处理后者的可能性,p必须知道其他牧师使用的比lastTried[p]更大的投票编号。可以通过扩展协议来实现,可以要求如果牧师q从p处收到了NextBallot(ba)消息或者BeginBallot(ba, d)消息,并且b<nextBal[q],那么他会给p发送一个包括nextBal[q]的消息。牧师p将用一个更大的投票编号来初始化一次新的投票。

依然假定只有单个牧师p正在发起投票,假定他需要发起一次新投票当且仅当: (i)p在之前的22分钟之内没有成功执行步骤3或步骤5,或者(ii)他知道另一个牧师已经初始化一个更大编号的投票。如果p锁了会议厅的门并且大多数牧师在里面,那么一个法令将会在99分钟之内被通过并且纪录在会议厅所有牧师的分类账上。(可能是p用22分钟的时间开始下一次投票,又一个22分钟的时间发现另一个牧师已经发起了一个更大编号的投票,然后55分钟的时间来完成步骤1-6,投票成功。)因此,如果只有单个不离开会议厅的牧师在发起投票,进程条件将会被满足。

完整的协议因此包括一个程序来选择单个牧师(被称为总统),来发起投票。在大多数政府中,选择一个总统是个很困难的问题。然而,因为大多数政府要求任何时候都只有一位总统,这才是困难的原因。例如,在美国,如果某些人认为布什当选总统,而另一些人认为杜卡基斯当选总统,就会产生混乱。因为他们其中一个或许会决定将一个提案写进法律而另一个决定否决该提案。然而,在Paxos的会议中,有多个总统或许只会阻碍进展,不会造成不一致性。对于满足进展条件的完整的协议,选择总统的方法只需满足下列总统选择条件:

如果没有人进入或离开议会厅,那么在T分钟之后,议会中只有一个牧师认为他自己是总统。

如果满足总统选择要求,那么完整的协议将会有属性——如果大多数的牧师在会议厅并且T+99分钟内没有人进入或者离开会议厅,那么T+99分钟之后,会议厅中的每个牧师的分类账上,都会有一个法令。

Paxos居民将会议厅中所有牧师的姓名按字典序进行排序,谁的姓名在最后,谁就被选为总统,尽管我们不知道为什么要这么做。如果会议厅中的牧师至少每T-11分钟一次给其他每个牧师发送包含他姓名的消息,总统选择条件将会被满足,并且,当且仅当牧师T分钟内没有收到来自“更高姓名”的牧师的消息,他将会认为他自己是总统。

完整的会议协议是从基本协议中得来,并要求牧师及时执行2-6步,加入了选择总统(总统负责发起投票)的方法,并且要求总统在适当的时候(T分钟后)发起投票。协议的许多细节还不知道。本文已经描述过选择总统的简单方法以及决定什么时候总统应该发起一次新投票的简单方法,但是他们明显不是Paxos居民使用的方法。本文所列的方法需要总统在已经选好法令之后,依然发起投票,以此来确保刚刚进入会议厅的牧师知道选中的法令。很明显,有更好的方法使牧师知道已经选中的法令。同样的,在选择总统的过程中,每个牧师也可以发送lastTried[p]的值给其他的牧师,使得总统在第一次发起投票时,选择一个足够大的投票编号。

Paxos居民意识到任何实现进展条件的协议一定要包括测量时间的流逝。上述给出的选择总统以及发起投票的协议可以通过设置计时器以及当超时发生时,做出相应的行为(假定计时器完美准确),很容易被制定为精确的算法。更进一步的分析显示,这样的协议可以在计时器的精度有界的情况下起作用。Paxos熟练的技工可以构建合适的沙漏计时器。

在Paxos数学家的深思熟虑下,大家相信,他们一定找出了满足总统选择条件的最佳的算法。我们只能希望这个算法在对于Paxos小岛的进一步研究中被发现。

3. 多法令议会

多法令议会初建时,满足一致性和进展需求的协议从上述单法令协议派生出。3.1和3.2节描述了原始多法令议会协议的产生以及属性。3.3节讨论了协议的进一步发展。

3.1 多法令议会协议

除了只通过一条法令,Paxos议会还需通过一系列有序法令。和在单法令会议协议中一样,需要选举一个领导者。任何人想要通过法令,需要通知领导者,领导者给法令分配一个编号并且尝试通过该法令。逻辑上,多法令议会协议为每个法令执行一次单独的完整的单法令会议协议的实例。然而,单个总统被选择以完成所有这些实例,故协议的前两步总统只需执行一次

派生多法令议会协议的关键在于,在单法令会议协议中观察到,总统一直到第3步才选择法令或者法定人数。一个新选举的总统p给某个议员集合发送一条消息,这条消息作为多法令议会协议所有实例的NextBallot(ba)消息。(有无数个实例——每个法令一个实例。)议员q回复单个信息作为多法令议会协议所有实例第(2)步的LastVote消息。这个消息只包括有限数量的信息,因为q只在有限个实例中进行了投票。

当新总统从一个大多数集合中的每个成员那收到了回复,他就准备为多法令议会协议的每个实例执行步骤(3)。对于某些有限数量的实例,第(3)步中法令的选择将由B3决定。对于这些实例,总统立即执行步骤(3)来通过这些法令。那么,无论总统什么时候收到想要通过法令的请求,他会选择能自由选择的最小编号的法令,并且执行步骤(3)以尝试通过这个法令。

对这个简单协议进行下列修改就变成了Paxos多法令议会协议:

——对于已经知道结果的法令号码,不需要执行协议。因此,如果一个新选举的总统p在他的分类账中写有号码小于等于n的所有法令,那么他会发送一个NextBallot(ba, n)消息作为多法令议会协议中法令号码大于n的所有实例的NextBallot(ba)消息。议员q对这条消息进行响应,通知p所有编号大于n并且已经出现在q分类账中的法令(此外对于不在q分类账中的法令还发送通常的LastVote信息),并且q请求p发送不在他分类账中编号小于等于n的法令。

——假定法令125和126在上周五下午被提出,法令126成功通过并且被写在一个或者两个分类账中,但是在其他事情发生之前,议员们都回家过周末了。假定接下来的周一∆φωρκ被选举为新总统并且知道了法令126,但是她不知道法令125,因为之前的总统以及为法令125投过票的所有议员都离开了议会厅。她将会举行一次投票来通过法令126,这么一来,分类账上将会有一个125的缺口。给一个新的法令分配125编号将会使该法令在法令126之前,而法令126是在上星期通过的。以这种方式乱序地通过法令可能会造成混淆——例如,提出新法令的市民之所以提出新法令是因为他知道法令126已经通过。所以,∆φωρκ会尝试通过一个传统的法令,该法令不会对Paxos岛上的任何人造成影响:

125:二月份是全国橄榄日

通常,一个新的总统会以通过“橄榄日”法令的方式填充他分类账上的空白

多法令议会协议的一致性和进展属性从单法令会议协议的对应属性派生而来。根据我们的了解,Paxos居民没有纪录多法令议会协议的精确描述,因为多法令议会协议只是单法令会议协议简单的派生。

3.2 多法令议会协议的属性

3.2.1 法令的顺序

多个不同法令的投票可能并发发生,投票由不同的议员发起——每个议员在发起投票时,都认为自己是总统。我们不能准确地说出法令会以什么顺序被通过,特别是在不知道总统是怎么选举的情况下。然而,我们可以推导出关于法令顺序的一个很重要的属性。

我们说法令被提出,是总统在步骤3中选择该法令作为会议协议的对应实例。我们说法令通过,是当它被第一次写在分类账上。在总统提出任何法令之前,他必须从一个大多数集合中的每个成员那获取他们进行过的选票的信息。已经通过的任何法令一定被这个大多数集合中至少一个议员投过选票。因此,总统在发起新投票之前一定已经知道所有之前通过的法令。总统不会用重要的法令(也就是除了“橄榄日”法令以外的任何法令)来填充分类账中的空白。他也不会乱序地提出法令。因此,协议满足下列法令顺序属性:

如果法令A和B是重要的法令并且法令A在法令B被提出之前已经通过了,那么法令A比法令B有一个更小的法令号码。

3.2.2 如果没有人进入或离开议会厅

尽管我们不知道具体选举新总统的细节,但是当总统被选举之后,并且没有人进入或者离开会议厅时,我们知道议会是如何工作的。在收到一个通想要过法令的请求之后——或者直接从市民那收到或者从另一个议员那收到——总统会分配给法令一个编号并且通过以下信息交换来通过它:(编号是指会议协议中相应的步骤)

(3)总统给法定人数中的每个议员发送一个BeginBallot信息。

(4)法定人数中的每个议员给总统发送Voted信息。

(5)总统给每个议员发送Success信息。

假定一个议会有N个议员和大约N/2的法定人数的话,这总共有三个消息延迟,大概有3N个消息。此外,如果议会很忙的话,总统会将一个法令的BeginBallot消息和上一个法令的Success消息一起发送,这样每个法令只有大概2N个消息。

3.3 进一步发展

管理小岛比Paxos居民认为的要更加复杂。一些问题出现了,他们需要对协议做出改变。一些最重要的改变如下所述。

3.3.1 选举新总统

首先用之前所提方法(只基于姓名的字母表顺序)来选择议会的总统。因此,当议员Ωκι从长达6个月的度假中回来的时候,他被立即任命为总统——即使他不知道在他缺席期间发生了什么。议会活动停止了,而Ωκι,纪录地很慢,努力地复制6个月的法令,使他的分类账最新。

这次事故引起了一场关于最好的选择总统方法的辩论。一些Paxos居民认为一旦一个议员成为了总统,他将一直是总统,直到他离开议会厅。一组有影响力的公民想要议会厅里最富有的议员成为总统,因为他能雇佣更多的法学家以及仆人来帮助他履行总统的职责。他们争论,一旦一个富有的议员保证他的分类账是最新的,就没有理由不让他担任总统。然而,其他人,认为最正直的公民应该成为总统,不管财富的多少。正直意味着不太可能是不诚实的,尽管没有Paxos居民在大庭广众下承认官员渎职的可能性。不幸的是,这场辩论的结果并不知道,没有最终使用的总统选举协议的记录。

3.3.2 厚的分类帐

随着时间的流逝,议会通过了越来越多的法令。Paxos居民不得不翻阅一长串法令来寻找目前的橄榄税或者什么颜色的山羊可以售卖。在一次长期的航程之后返回议会厅的议员必须复制很多内容使自己的分类账保持最新。最终,议员被迫将他们的分类账从法令清单转化为法律书籍,法律书籍只包含法律当前状态以及在该状态下通过的最后一条法令的编号。

为了知道当前的橄榄税,人们在法律书中查找“税收”;为了知道什么颜色的山羊可以售卖,人们在法律书中查找“商业法律”。如果一个议员的分类账包含法令1298的法律,并且他知道法令1299将橄榄税设置为每吨6德拉马克,他只会改变橄榄税法律的条目,并且记下他的法令已经到了1299。如果他接下来知道法令1302,他会将法令1302写在分类账的后面,并且一直等待,直到他知道法令1300和1301,之后,将会把法令1302合并进法律书。

为了让短时间离开的议员在不复制整本法律书的情况下追赶上进度,议员在书的背面记下过去一周的法令清单。他们可能将清单记在一张纸上,但是对于议员来说,将通过的法令记在分类账上,并且一周更新法律书2~3次是很方便的。

3.3.3 官僚体系

随着Paxos日益兴旺,议员也越来越忙。议会不能够处理政府的所有细节,所以设立了官僚体系。议会通过一条法令来任命一个奶酪检察院来做决定,而不是通过一个法令来宣布是否每一批奶酪都可以销售。

很快发现选举官僚并不像一开始以为的那样简单。议会通过了一条法令,任命∆˘ικστρα是第一个奶酪监管员。在几个月之后,商人抱怨∆˘ικστρα太严格了,拒绝了很好的奶酪。议会接着通过了法令来替代他:

1375:Γωυδα是新的奶酪监管员。

但是∆˘ικστρα并没有密切关注议会的决定,所以他没有马上知道这条法令。奶酪市场有一段时间的混乱,因为∆˘ικστρα和Γωυδα都检查奶酪并且做出了冲突的决定。

为了防止这样的混乱,Paxos居民必须保证一个位置在任何时间最多只有一位官员。为了实现这个保证,总统提出法令时将日期以及时间作为法令的一部分。一个任命∆˘ικστρα为奶酪监管员的法令为:

2716: 72年1月15日8:30——∆˘ικστρα担任3个月的奶酪监管员

这条法令说明了∆˘ικστρα的任职期或者是从1月15号8:30开始,或者是在之前的监管员任职期限到了之后——以较晚者为准。他的任职期将在4月15号8:30结束,除非他要求总统通过一条这样的法令来辞职:

2834: 72年4月3号9:15——∆˘ικστρα作为奶酪监管员辞职

一个官员被短期任命,所以它可以快速被替换——例如,如果他离开小岛的话。如果官员的工作令人满意的话,议会将会通过一条法令来延伸官员的任期。

时间用来确定官僚们目前是否担任职务。Paxos居民并不知道机械时钟,但是Paxos居民能通过太阳或者星星的位置来判断时间,精度在15分钟之内。如果∆˘ικστρα的任期在8:30开始,他将会在他观察到8:45的时候才开始监管奶酪。

如果较高编号的法令总是有较迟的提议时间,这种任命官员的方法很容易起作用。但是,如果议会通过下列法令:

2854:78年4月9号9:45——ΦρανσΦζ担任2个月的红酒品尝师

2855:78年4月9号9:20——ΠνυΦλ˘ι担任1个月的红酒品尝师

这两条法令是在9:30-9:35期间由不同的议员(都认为他们自己是总统)提出。这样无序的提议时间很容易被避免,因为议会协议满足下列属性:

如果两个法令由不同的总统通过,那么一个总统在得知另一个法令已经被提出之后才提出他自己的法令。

为了证明满足这个属性,假定法令D在投票编号为ba的投票中成功通过,法令D’在投票编号为ba’的投票中成功通过,并且ba<ba’。q为在这两次投票中进行过投票的议员。D’的投票以NextBallot(ba’, n)消息开始。如果消息的发送者还不知道D,那么n要小于D的法令号码,那么q对于NextBallot消息的回复一定包含他已经投票给D的信息。

3.3.4 学习法律

除了请求通过法令,普通的居民需要查询小岛上最近的法律。Paxos协议首先考虑居民可以查阅任何议员的分类账,但是下列事件表明,需要一个更复杂的方法。几个世纪以来,只卖白山羊是合法的。名为∆ωλΦφ的农民让议会通过法令:

77:允许售卖黑山羊

∆ωλΦφ接着让他的牧羊人将一些黑山羊卖给名为ΣκΦΦν的商人。作为一名遵守法律的市民,ΣκΦΦν询问议员ΣτωκµΦ˘ιρ这样的买卖是否合法。但是ΣτωκµΦ˘ιρ已经离开了议会厅,并且在他的分类账上法令76之后就没有条目了。他建议ΣκΦΦν这次买卖在当前法律下是不合法的,所以ΣκΦΦν拒绝购买这些山羊。

这一事件导致下列关于法律查询的单调性条件的形成:

如果一次查询先于第二次查询,那么第二次查询不能获得比第一次查询更早的法律状态。

如果一个居民得知一个特定的法令已经通过,那么获取这个法令的过程就是这个单调性条件适用的隐式的查询。单调性条件的解释随着时间而发生变化。

一开始,通过为每次查询通过一个法令来实现单调性。如果Σ∂ν˘ιδΦρ想要知道当前橄榄税,他将会使议会通过一条如下的法令:

87:居民Σ∂ν˘ιδΦρ正在读法律

他将会查询任何至少通过了法令86的分类账来了解橄榄税。如果居民ΓρΦΦς接着再查询橄榄税,他的查询的法令是在法令87通过之后提出的,所以根据法令顺序属性他会收到一个比87更大法令号码。因此ΓρΦΦς不会比Σ∂ν˘ιδΦρ获得一个更早的橄榄税的值。这种查询法律的方法满足单调性条件,这里,“先于”被理解为,当且仅当A完成在B开始之前,才能说查询A“先于”查询B。

很快发现为每个查询通过一条法令很麻烦。Paxos居民意识到如果他们通过改变“先于”的语义来减弱单调性规则,会有一个更简单的方法。他们决定对于一件先于另一件的事,第一件事不止要在更早的时间发生,而且他必须要在因果关系上对第二件事有影响。更弱的单调性条件防止了农民∆ωλΦφ和商人ΣκΦΦν遇见的问题,因为在∆ωλΦφ隐式的查询结束和ΣκΦΦν开始查询之间有一个事件的因果链。

更弱的单调性条件通过在所有的商业交易和查询中使用法令号码来满足。例如,农民∆ωλΦφ,拥有许多不是白的山羊,让议会通过法令:

277:棕山羊的买卖是被允许的

当将他的棕山羊卖给ΣκΦΦν的时候,他通知商人,这次买卖因为法令277是合法的。ΣκΦΦν接着询问议员ΣτωκµΦ˘ιρ根据至少通过了法令277的法律来看,这次买卖是否是合法的。如果ΣτωκµΦ˘ιρ的分类账上没有完成法令277,他会等待通过法令277或者通知ΣκΦΦν去问其他人。如果ΣτωκµΦ˘ιρ的分类账上通过了法令298,那么他会告诉ΣκΦΦν根据法令编号298,这次买卖是合法的。商人ΣκΦΦν将会记住法令298为了在他下一次商业交易或者法律查询中使用。

Paxos协议已经满足了单调性条件。但是普通的市民不喜欢记法令号码。再一次地,Paxos居民通过重新解读单调性条件来解决这个问题——这一次,通过改变法律状态的含义。他们将法律分为不同的领域,每个领域选择一个议员作为专家。法律的每个领域的当前状态由专家的分类账决定。例如,假定法令1517改变了关税并且法令1518改变了税收法律。如果税收法律的专家在关税法律的专家知道其中一个法令之前知道了这两个法令,税收法律将会首先改变,产生了一种以数字顺序制定法律所不能得到的法律顺序。

为了避免当前状态的冲突的定义,Paxos协议需要在任何领域一次最多只能有一位专家。这个需求通过使用和选官僚(3.3.3)相同的方法来选择专家来实现。如果每次查询只包括法律的单个区域,单调性通过将查询转向领域的专家来实现,领域的专家根据分类账上的内容进行回答。既然知道一条通过的法令会构成一次隐含查询的结果,Paxos协议要求一条法令最多只能改变法律的一个领域,并且法令通过的通知只能来自于这个领域的专家。

包含多个领域的查询不难解决。当商人Λισκωφ询问是否进口金色羊毛的关税比本地购买的销售税要高,关税和税收专家必须合作来提供答案。例如,税收专家可以通过首先询问关税专家进口羊毛的关税,然后回答Λισκωφ,只要他在收到回复之前不改变他的分类账。

在需同时对法律的若干领域进行彻底改变之前,这种方法是令人满意的。接着,Paxos居民意识到维持一致性的必要需求不是一条法令只影响一个领域,而是法令影响的每个领域有相同的专家。议会通过任命单个议员为所有这些领域的专家,实现用单条法令来改变法律的几个领域。此外,只要法律的领域不改变,相同的领域可以有多个专家。在所得税到期之前,议会将任命多个税法专家来处理关于税法的大量询问。

3.3.5 不诚实的议员以及诚实的错误

尽管官方声称所有议员都是诚实的,但是在Paxos历史上,一定有一些不诚实的议员。当这些不诚实的议员被抓住,他们就会被放逐。通过发送矛盾的信息,一名恶意的议员可能会导致不同议员的分类账不一致。不一致也有可能由诚实议员或者信使一段时间的失忆导致。

当意识到不一致性,可以通过法令很容易地纠正。例如,关于当前橄榄税的不一致性可以通过让议会通过一条新法令来规定税值来消除。困难在于在没有人意识到不一致性的时候纠正不一致的分类账。

议员不诚实或者错误的存在可以从议会建立几年后开始在分类账中出现的冗余法令推断出来。例如,即使法令2155已经将橄榄税设置为每吨9德拉马克,并且没有干预的法令改变它,下列法令依然通过了:

2605:橄榄税为每吨9德拉马克

议会似乎每六个月循环它的法律,以便于即使议员的分类账一开始不一致,所有的议员将会在六个月之内就当前法律达成一致。大家相信,通过这些冗余法令的使用,Paxos协议使他们的议会自我稳定。(自我稳定是现代词汇,由Dijkstra提出)。

并不十分清楚在一个议员随意进出的议会,自我稳定意味着什么。Paxos居民不会乐意在一致性得到保证之前,需要所有的议员同时在议会厅里。然而,实现一致性要求如果一个议员在他的分类账中有一个特定法令号码的条目并且另一个议员没有,那么第二个议员将最终会填上该条目。

不幸的是,我们不知道Paxos协议实现了哪种自我稳定属性或者他们是如何实现的。Paxos岛上的数学家毫无疑问解决了这个问题,但是他们的工作还没有被发现。我希望将来的考古学家去Paxos小岛上考察的时候,将会优先搜索关于自我稳定的手稿。

3.3.6 选择新议员

首先,议会的成员资格是遗传的,由父母传给孩子。当较老的政治家Παρνας 退休,他将他的分类账传给他的孩子,进行不中断的纪录。这不对和Παρνας交流的议员产生影响。

随着之前的家族移民,新的家族搬入,系统必须进行改变。Paxos协议决定通过法令进行议会成员的加入和移除。这造成了循环问题:议会的成员资格由通过的法令决定,但是通过法令需要知道一个大多数集合有哪些人,这将取决于谁是议会的成员。可以通过由法令n-3指定通过法令n使用的议会的成员资格来打破这个循环。直到总统知道法令3252之前的所有法令,他才尝试通过法令3255。在实际中,在通过下列法令之后:

3252:Στρωνγ现在是一个议员

总统将立即通过法令3253和法令3254,他们都是“橄榄日”法令。

以这种方式改变议会的组成是很危险的,一定要小心。一致性和进展条件将总会保持,然而,只有在大多数牧师在会议厅内,进展条件才可确保进展。当大多数牧师曾经在会议厅内,并不能确保进展。事实上,选择议员的机制导致了议会系统在Paxos的倒台。因为一个法学家的错误,一条应该褒奖在沉船中淹死的水手的法令变成了任命他们为议会的成员。这条法令的通过阻止了任何新法令的通过——包括为了纠正这个法令提出的法令。Paxos的政府停止运行。一个名为Λαµπσων的将军利用这个混乱发动了政变,建立了军事专政政府,结束了几个世纪以来进步的政府。Paxos在一系列腐败的专政下越来越弱,并且不能击退来自东边的入侵,导致了它的文明的灭亡。

4. 与计算机科学的相关性

4.1 状态机方法

尽管Paxos议会已经被毁灭几个世纪了,它的协议仍然是有用的。例如,考虑一个简单的被用于域名服务器的分布式数据库系统。数据库的状态包括将值分配给名称。数据库的副本由多个服务器维持。一个客户程序能发出请求给任何服务器,一个读请求或者一个改变名称的写请求。有两种读请求:一种是慢读,将返回当前分配给某个名称的值,一种的快读,更快一点但是或许不会反映出数据库最近的改变。

在这个数据库系统和Paxos议会之间有一种明显的对应关系:

议会  分布式系统

议员  服务器

居民  客户程序

当前法律数据库状态

图2 简单数据库的状态机

客户端改变值的请求由通过一条法令来执行。一次慢读包括通过一条法令,像3.3.4描述的那样。一次快读由读取服务器当前的数据库版本来实现。Paxos议会协议提供了一种分布式,容错的数据库系统的实现。

实现分布式数据库的方法是状态机方法的一个实例,最早由Lamport在1978年提出。在这种方法中,一个人首先定义一个状态机,状态机包括一组状态集,一组命令集,一组响应集,还有一个函数,函数将响应/状态对(一对包括一个响应和一个状态)分配给每个命令/状态对。直观地,一个状态机通过产生一个响应以及改变它的状态来执行一个命令;命令和机器的当前状态决定了它的响应和它的新状态。对于分布式数据库来说,一个状态机的状态只是一个数据库状态。状态机的命令以及指定响应和新状态的函数在图2中有描述。

在状态机方法中,系统由服务器组成的网络实现。服务器将客户端请求变为状态机命令,执行命令,将状态机响应转化为对客户端的回复。一般算法确保了所有的服务器具有相同的命令序列,从而确保了他们都产生相同的响应以及状态转换序列——假定他们都从相同的起始状态开始。在数据库例子中,客户端请求执行一次慢读或者改变一个值被转化为一次状态机的读或者更新命令。这个命令被执行,状态机响应转化为对客户端的回复,通过收到客户端请求的服务器来发送客户端回复。既然所有的服务器执行相同的状态机命令序列,他们全都保持数据库版本的一致性。然而,在任何时间,某些服务器可能比另一些服务器有更早一点版本,因为一个状态机命令不需要所有的服务器在相同的时间执行。一个服务器使用他当前版本的状态去回复一次快读请求,不执行状态机命令。

系统的功能用状态机表示,状态机是从命令/状态对到响应/状态对的函数。同步和容错问题由一般算法解决,使得服务器获得相同的命令序列。当设计一个新系统时,只有状态机是新的。服务器通过一个已经被证明是正确的标准的分布式算法来获取状态机命令。函数比分布式算法更容易设计,更容易正确。

实现一个任意状态机的第一个算法在由Lamport在1978年提出。随后,设计了容忍任意固定数量(f)故障的算法[Lamport 1984]。这些算法确保了如果少于f个进程故障,那么状态机命令会在一个固定时间范围内被执行。这个算法因此适于需要即时响应的应用。但是,如果超过f个故障发生,那么不同服务器或许有状态机不一致的副本。此外,两台服务器之间不能彼此交流相当于一台服务器故障。对于一个几乎不会丢失一致性的系统来说,它必须使用f很大的算法,反过来,会在冗余的硬件,交流带宽以及响应时间上有更多的花费。

Paxos议会的协议提供了另一种方式来实现一个任意状态机。议员的法律书对应于机器状态,并且通过一条法令对应于执行一个状态机命令。得到的算法比起早期的算法没有那么强健,但花费也不大。它并不容忍任意的恶意的故障,也不能保证有界时间的响应。然而,在任意数量的(良性的)进程故障以及交流路径故障下,能保证一致性。Paxos算法适用于需要适度可靠性要求的系统,不需要为严苛的容错,即时的实现提供花费。

如果状态机由一个保证边界响应时间的算法执行,那么时间也可以是状态的一部分,机器的行为可以由时间的流逝被触发。例如,考虑一个分配资源的系统。状态可以包括客户被授予资源的时间,并且如果客户拥有资源太长时间,状态机可以自动执行命令收回所有权。

在Paxos算法中,时间不能以这种自然的方式成为状态的一部分。如果故障发生,可以花费任意长的时间去执行一条命令(通过一条法令),并且一条命令能在另一条更早提出的命令(在法令序列中出现地更早)之前被执行。然而,状态机仍可以像Paxos议会一样使用真实时间。例如,在3.3.3描述的决定谁是当前奶酪监管员的方法可以被使用去决定谁是当前资源拥有者。

4.2 提交协议

Paxos的会议协议类似于标准的三阶段提交协议。一次Paxos投票和一个三阶段提交协议都在协调者(总统)和其他的法定成员(议员)之间有5个信息交换。一个提交协议选择1-2个值——提交或中止——但会议协议选择任意的法令。要将一个提交协议转换为一个会议协议,需要在第一轮消息中发送法令。提交意味着法令通过,中止决定意味着“橄榄日”法律被通过。

会议协议与转化的提交协议不同,因为法令直到第二阶段才发送。这允许相应的会议协议对于所有的法令只执行一次第一阶段,所以通过每个法令只需要3次信息交换。

会议协议基于的理论类似于Dwork,Lynch和Stockmeyer获得的结果。然而,他们的算法在单独的轮次依次执行投票,并且似乎和会议协议无关。

自从这篇文章写出来之后,这个领域已经做了许多调查。Schneider已经调查了状态机方法。Keidar和Dolev的恢复协议[1996]以及Fekete等人的完全顺序广播算法[1997]和这里描述的Paxos协议很相似。作者也似乎不知道,Oki和Liskov[1988]的视图管理协议似乎和Paxos协议一样。

这篇文章中提到的许多修订也出现在当代或者后续的文章中。3.3.3中描述的委托方法和Gray及Cheriton提出的租约机制[1989]很像。3.3.4中Paxos使用法令号码来满足单调性条件的技术是由Ladin等人描述的[1992]。3.3.6的增加新议员的技术由Schneider提出[1990]。

附录(略,参见原文)

Paxos算法《The Part-Time Parliament》译文相关推荐

  1. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

  2. 微信PaxosStore:深入浅出Paxos算法协议

    引言 早在1990年,Leslie Lamport(即 LaTeX 中的"La",微软研究院科学家,获得2013年图灵奖)向ACM Transactions on Computer ...

  3. 图解分布式一致性协议 Paxos 算法【BAT 面试题宝库附详尽答案解析】

    0. 问题场景 1.Paxos 简介 Paxos is a family of protocols for solving consensus in a network of unreliable p ...

  4. Paxos 算法浅析

    Paxos 算法浅析  xiewen 关注 2016.07.19 17:24* 字数 3613 阅读 3740评论 0喜欢 22 持续更新 如何浅显易懂地解说 Paxos 的算法? 参考资料 #8:知 ...

  5. 世上只有一种一致性算法,那就是Paxos ,所有其它一致性算法都是Paxos算法的不完整版!

    前言 最近在研究Paxos算法,提到分布式算法,就不得不提 Paxos 算法,在过去几十年里,它基本上是分布式共识的代名词,因为当前最常用的一批共识算法都是基于它改进的.比如,Fast Paxos 算 ...

  6. 架构设计:系统存储(23)——数据一致性与Paxos算法(上)

    今年年初参加一家公司的面试,发生了一件有趣的事情.当我给面试官解释Ceph的运行原理时,提到了Ceph支持POSIX标准(Portable Operating System Interface),面试 ...

  7. Paxos算法原理和过程解析

    我们了解了2PC和3PC之后,我们可以发现,无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题以及无法解决太过保守及容错性不好.Google Chubby的作者Mike Burrows说过 ...

  8. 深入浅出理解Paxos算法

    Paxos算法是莱斯利·兰伯特(英语:Leslie Lamport,LaTeX中的「La」)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法. Paxos算法一开始非常难以理解,但是一 ...

  9. Paxos算法之旅(四)zookeeper代码解析--转载

    ZooKeeper是近期比较热门的一个类Paxos实现.也是一个逐渐得到广泛应用的开源的分布式锁服务实现.被认为是Chubby的开源版,虽然具体实现有很多差异.ZooKeeper概要的介绍可以看官方文 ...

最新文章

  1. samtools 检测bam文件的完整度
  2. [No000077]打造自己的Eclipse
  3. SQL Server AlwaysOn中的几个误区
  4. WuJiuVideoX视频小说图片站群程序开源源码
  5. aix查看oracle进程内存,Aix 查看进程占用内存大小(按从大小排列)
  6. easypoi 大数据 百万_scrapy 解决爬虫IP代理池,百万大数据轻松爬取。
  7. vs如何运行外部 C++ 文件
  8. WangEdit富文本编辑器图标修改
  9. 如何一步步学习到精通JavaScript
  10. Spring定时器@Scheduled
  11. [转]Excel插件开发基础知识
  12. 一种简单的不净观(女人)方法,帮助看破色欲
  13. activex控件 java_ActiveX控件不自动安装
  14. 用计算机弹生僻字乐谱,生僻字 E调(拇指琴卡林巴琴弹奏谱)
  15. 阿里云ACP认证适合什么样的人考?
  16. iOS 控制任务执行顺序
  17. css表格文字位置调整,word表格中的文字距离表格四周太远,怎么才能调的近一些,除了调字大小。...
  18. 深谈德国车和日本车的区别--觉得分析的还算冷静客观
  19. Mac电脑装centos虚拟机网络设置
  20. .net remoting http://www.cnblogs.com/wayfarer/archive/2004/07/30/28723.html

热门文章

  1. OpenMLDB + OneFlow: 手把手教你快速链接特征工程到模型训练
  2. PADS VX1.2安装包和破解包
  3. 【夸夸其谈】关于“佛系”游戏和玩家的一些想法
  4. Excel中错误类型
  5. Linux驱动:input输入子系统
  6. 防疫宣传二维码有哪些优势?
  7. yii2发送邮件(配置QQ版本)
  8. 3ds Max人物女性角色模型建模教程
  9. 用java魔幻粒子_魔幻粒子模拟解压
  10. 联想旧电脑装Linux,改为网站服务器 - Part 1