Part 2:Re-visiting of Paxos Made Simple(再读Paxos算法)

“声明:由于个人水平有限,文中若存在不妥或错误之处,欢迎大家拍砖,并且一起讨论,交流。在文中会引用其他专家学者的观点和理论等内容,如文中出现版权问题,请联系我,我将以最快的速度删除。”

1 简介

实现容错分布式系统的Paxos算法被认为很难理解,也许是因为原始的论文对于许多读者来说,演示文稿通过假设希腊城邦议会工作机制这种形式呈现的[5]。 实际上,Paxos算法是最简单,最明显的分布式算法之一。核心是共识算法-“ synod”算法[5]。下一章说明共识算法满足了我们想要它满足的所有属性。最后一部分介绍了完整的Paxos算法,其中通过将共识直接应用到用于构建分布式系统的状态机方法中,该方法应该众所周知,因为它可能是最常被引用的关于分布式主题的系统理论文章[4]。

2 共识算法

2.1 问题

假设一组进程中的任意进程都可以对某个问题提出自己的解决方案(例如,针对系统中某个变量的取值问题提出不同的建议值)。共识算法可确保在提议的所有建议值中选择一个。如果没有任何进程提出提出任何一个建议值,则系统中不应为这个变量选择任何值。如果已经有一个建议值被选为这个变量的最终取值,那么,系统中的所有进程应该都能够学习到这个值。安全达成共识的要求是(即达成共识需要系统中满足的Safety属性):

* 只有被提议的值可被选为最终值(也就是说,最终取值必须来自所有的提议值中);

* 只有一个提议值会被选为最终值;

* 系统中的某个进程永远不会学习到一个没有被最终选择的值,(也就是说,除非一个提议值被选为最终值,否则,这个值不应该给系统中的进程学习到)。

我们不会尝试指定精确的系统中进行共识算法时需要满足的Liveness属性。但是,算法的目标是确保最终选择一些被提出的值,而且,如果有一个提议值被选为最终值,那么系统中的涉及该算法的任一进程都将最终学习到这个最终值。 我们在共识算法中使用了三个角色:Proposer,Acceptor和Learner。在具体实施中,一个进程可以扮演其中一个、两个或者三个代理人。

# Proposer:系统中存在多个Proposer,针对某个问题提出解决方案,即对a的下一次的取值给出任一提议值;

# Acceptor:系统中存在多个Acceptor,针对Proposer的提议值进行投票,以表示支持哪些Proposer;

# Learner:系统中存在多个Learner,当Acceptor们的投票产生了结果,即同意了某个Proposer的提议值,那么系统中的所有Learner最终(即时间上可能存在很大的跨度)都会学习到这个表决结果。

假定代理可以通过发送消息相互通信。我们使用惯用的非拜占庭式异步模型,其中:

* 代理以任意速度运行,可能因停止而失败,并且可能重新开始。由于选所有的代理角色都可能存在这样的情况:在系统中选出一个最终值后,代理角色失败然后重新启动。这种情况下,如果这些代理角色不记录选举过程中的一些数据的话,这样的共识算法是不可能实现的。

* 邮件可能需要花费很长时间才能传递(即消息的延迟时间不定且可能很长),消息可以重复传递,并且消息可以丢失,但它们不会被篡改(即消息的内容在传输过程中不会被改动)。

2.2 选中一个Value

choosing value就是从多个提议值中选出一个最终值。这里可以假设系统中存在多个进程,每个进程中都有一个变量a,而且,系统中的所有的保存变量a的进程最终会对a的下一个值达成共识。如现在在所有的进程中a=1,现在要对a的下一个choosing value进行协商,每个进程都可以对a的下一个choosing value进行提议,Paxos算法能够保证,虽然每个进程对a的提议值不同,但是经过Paxos算法后,可以保证系统中所有进程都会知道a的下一个取值是相同的,如a=2。这里,a=2表示系统中a这次取值就为2,从a=1到a=2这个过程就是Paxos算法执行过程,a=2这个状态就是Paxos算法达到的目的,但是,目的是尽快完成a的下一次choosing value,究竟下一次取值是什么不是Paxos算法考虑的。

choosing value的最简单方法是系统中仅仅设置一个Acceptor。所有的Proposer将提议值发送给这个Acceptor,这个Acceptor选择它收到的第一个提议值作为最终选定的值。这个方法虽然简单,但该解决方案并不令人满意,因为单个Acceptor存在单点问题,一旦这个Acceptor出故障,那么系统就瘫痪了。 因此,让我们尝试另一种方法。让系统中存在多个Acceptor。Proposer将提议值发送给所有Acceptor中的一组Acceptor(部分)。每一个Acceptor都可以接受来自任何Proposer的提议值作为最终的值。当足够多的Acceptor都选择了某个Proposer的提议值,那么这个Proposer的提议值就成为本次选出的最终值。那么,这里的“足够多Acceptor”是需要多少?为了确保系统中最终只选择一个提议值,我们可认为“足够多Acceptor”表示“大部分Acceptor”。因为如果一个Acceptor可以同意最多一个提议值,任何两个大多数Acceptor组中至少有一个共同的Acceptor。(大多数人的结论很明显在许多论文中都已观察到,这个理论可在文献[3]中找到。)也就是说,两组Acceptor中至少有一个Acceptor同时出现在两个Acceptor组中,这样可以确保两组Acceptor不会出现不同的选择。 在没有失败或消息丢失的情况下,我们希望系统中可以choosing value,即使只有一个Proposer提出一个提议值。这表明需求:

P1. An acceptor must accept the first proposal that it receives.

P1. 一个Acceptor必须接受它收到的第一个提议值。

“P1是为了保证算法的底线,哪怕只有一个Proposer提出提议值也能保证算法可完成choosing value这个操作。”

但是满足P1时增加了一个难题。同一时间,不同的Proposer可能会提出几个提议值,导致每个Acceptor都接受一个不同提议值的情况,但大多数Acceptor都拒绝接受该提议值。即使只有两个提议值,如果系统中有一个Acceptor出现故障,那么就可能存在每个值都被一半的Acceptor接收,这样就不存在大多数的Acceptor接收某一个提议值,这就导致了这次choosing value失败。

满足P1和满足仅在大多数接受者都接受的情况下才选择提议值的要求,意味着必须允许一个接受者接受多个提议。我们通过为每个提议分配一个(自然)编号来跟踪Acceptor可以接受的不同提议,因此提议由提议编号和提议值组成。为避免混淆,我们要求不同的提议具有不同的编号。如何实现不同的提议具有不同的提议编号取决于实现方式,因此现在我们仅假设这个要求可以实现。当具有该值(即提议编号)的单个提议已被大多数Acceptor接受时,将选择一个提议(包括提议里面的提议值)。在这种情况下,我们说已经选择了提议。

现在每一个Acceptor都可以接受多个提议(包含提议编号+提议值),那么我们必须保证所有的提议中都有相同的提议值(因为我们必须保证每一轮都只有一个提议值被选择,如果提议中的提议值不一样,那么就会破坏Safety属性:“只有一个提议值会被选为最终值”)。通过对提议编号的归纳,我们可知道下面的P2将能够保证Safety属性:

P2. If a proposal with value v is chosen, then every higher-numbered proposal that is chosen has value v.

P2. 如果具有某个提议值v的提议被选中,那么,所有带有较高提议编号的且最终被选中的提议须具有相同的提议值v。

“P2是为了保证:即使在一轮的选择中出现多个提议被Chosen(即被选中),也不会出现多个提议值被选中。”

因为提议中的提议的编号是全局有序增加的,所以P2可以保证“只有一个提议值会被选为最终值”。

再接着看,如果一个提议被选中,那么它需要先被Acceptor接受,因此,对P2的约束可以向前推,将约束推到Acceptor接受提议这个阶段,就有了下面的P2a:

P2a. If a proposal with value v is chosen, then every higher-numbered proposal accepted by any acceptor has value v.

P2a. 如果具有某个提议值v的提议被选中,那么,所有带有较高提议编号的且被Acceptor接受的提议须具有相同的提议值v。

“P2是也保证了:即使在一轮的选择中出现多个提议被Chosen(即被选中),也不会出现多个提议值被选中。”但是,相对于P2,P2a将约束向前推进到Acceptor进行接受的阶段。

满足P2a也任然要满足P1,那为什么要将约束向前推进呢?因为,在分布式系统中,节点之间的通信是异步的,这就导致可能出现这样的情况:某一个提议带有提议值可能被系统中其它的Acceptor接受,如果这些Acceptor还没有接收到任何提议的话(这是由P1约束的:任何没有接受过提议的Acceptor必须接受它收到的第一个提议)。这样的话,我们假设系统中有一个Proposer是刚启动的,而且它提出了一个带有较大提议编号的提议(其中的提议值不等于v),并且将这个提议发送给了一个Acceptor c,而Acceptor c没有接受过任何提议,那么Acceptor c必须接受这个提议,这就违背了P2a。

上面就说明,P2a很难被保证,那么我们需要继续对P2a进行约束向前推进,以保证P1和P2a都能够被满足,于是就有了下面的P2b:

P2b. If a proposal with value v is chosen, then every higher-numbered proposal issued by any proposer has value v.

P2b. 如果具有某个提议值v的提议被选中,那么,所有带有较高提议编号的且被Proposal提出的提议须具有相同的提议值v。

很明显,满足P2b必然满足P2a,因为提议的提出早于提议被接受,从提议提出阶段就限制其中的提议值必须相同,那么接受阶段肯定不会存在提议值不一样的情况。所以说,满足P2b就意味着满足了P2a和P2.

那么如何保证每个提议中携带的提议值满足P2b的要求呢?我们可以发现,当新提议被提出时,系统中的如果已经有被接受的提议值v,那么后面的提议(即编号更大的提议)只要都携带提议值v,那么就能保证P2b;或者,如果当新提议被提出时,系统中没有被接受的提议值,那么接下来的提议可以自己定这个提议值。这样,就能够保证一旦有一个提议值被接受,那么后面的所有提议都会尽可能的促使这个提议值被选中,从而结束这一轮的操作。(其实这里面的思想来源于Paxos的第一篇文章中的一个思想:每个议员都想尽快的完成某一轮的提案。只要大家尽量别提出不同提议值,那么一轮提案就很快能够通过。说白了就是,只要有人提议,后面所有人都同意,这样很快就能够完成一轮。原文里这样描述的:每个议员都是兼职的,所以大家并不怎么关心到底什么法令会被通过,大家关心的是尽快结束法令的投票,从而可以出去做生意赚钱,毕竟大家都是兼职的,赚钱才是要紧的)。

根据上面的思想,我们能够通过P2b的变体来满足,及P2c:

P2c. For any v and n, if a proposal with value v and number n is issued, then there is a set S consisting of a majority of acceptors such that either (a) no acceptor in S has accepted any proposal numbered less than n, or (b) v is the value of the highest-numbered proposal among all proposals numbered less than n accepted by the acceptors in S.

P2c. 对于任意的v和n,如果存在某个具有提议编号n和提议值v的提议被issued,那么,必然存在一个Acceptor的集合S,S满足(a)S中没有任何一个Acceptor接受了其它任何编号值小于n的提议;或者(b)v就是所有被接受的编号值小于n的提议中编号值最大的那个提议所携带的提议值。

P2c将约束提前至Proposer发出Proposal时刻了,注意:这里对Proposer的约束是在其发出accept请求时候,即隐含Proposer已经发出过prepare消息并确认过可以发出上述携带编号n和提议值v的请求。P2c的(a)说明:在该proposer收到的关于其发送的prepare的回复消息中没有得到关于其accept消息应该携带的提议值的信息,也就是说,所有回复该proposer的acceptor(数量满足大多数)没有接受过编号值大于n的prepare消息,而且,即使接受过编号值小于n的prepare消息,也没有接受过其后续accept消息中携带的提议值。P2c的(b)说明:如果P2c不满足,即回复其prepare消息的acceptor中有的acceptor已经接受了编号值小于n的提议,那么该proposer在自己发送的acceptor消息中携带的提议值就是v(这是为了尽快结束Paxos,所以尽可能的去与其它Proposer的提议值保持一致)。还要注意的是,如果此时的acceptor接收了多个编号小于n的提议,v应该是编号值小于n中最大的那个提议携带的提议值(只要大家都遵守P2c,那么其实只会有一个提议值被传递下去,这就保证了后面所有的提议都是围绕提议值v进行的,加快该轮Paxos正常结束)。

可以看出,只要能够保证P2c就能够保证P2b。

为了保证P2c,一个Proposer在发出一个携带编号n的提议前必须学习系统中编号值小于n且最大的那个已经或者即将被大多数Acceptor接受的提议信息。学习已经被接受的提议比较容易,但是预测未来会被接受的提议是比较困难的。一个Proposer通过提取来自Acceptor的承诺(承诺内容是:这个Acceptor不会接受提议编号小或者提议值不相同的提议)来保证P2c。换句话说,Proposer向Acceptor请求其不要接受提议编号小于n的其它任何提议来保证P2c,这就引出了下面的Proposer发送提议请求信息的算法:

[if !supportLists](1) [endif]一个Proposer选择一个新的提议编号n并向其它Acceptor(足够数量的)发送请求信息(即Prepare信息),请求Acceptor回复下面的信息:

a) 不要再接受任何提议编号值小于n的提议,而且,

b) Acceptor已经接受的提议编号值小于n中最大的那个提议的内容(如果存在的话)。

将这样的请求信息成为Prepare请求信息。

(2)如果Proposer接收到大多数的Acceptor的回复,那么这个Proposer可以发送一个提议信息(包含提议编号n和提议值v),其中,v是所有的Acceptor的回复消息中拥有最大提议编号值的那个提议携带的提议值,或者,v可以使这个Proposer任意提出的提议值,如果所有的回复消息中都没有相应的提议值信息。

一个Proposer发送一个提议信息给大多数的Acceptor(这些Acceptor不必是回复之前的Prepare信息的Acceptor),我们叫这样的信息为Accept请求信息。

上面描述了一个Proposer的算法,那么Acceptor的算法是什么呢?一个Acceptor可以接受来自Proposer的两种信息:Prepare请求信息和Accept请求信息。为了保证算法的安全,Acceptor可以忽略任意的来自Proposer的请求信息。一个Acceptor永远都可以恢复一个Prepare请求信息,但是,当且仅当一个Acceptor没有承诺过不接受其它提议,它都可以恢复一条Accept请求信息,也就是说:

P1a. An acceptor can accept a proposal numbered n iff it has not responded

to a prepare request having a number greater than n.

P1a. 只要一个Acceptor没有回复过任一个Prepare消息(且该消息携带的提议编号值大于n),那么这个Acceptor就可以接受一个提议编号值为n的新的Prepare请求信息或者Accept请求信息。

很明显,P1a包含了P1.

现在,我们有一个完整的算法来选择满足所需安全属性的值-假设使用唯一的建议编号。最终算法是通过进行一次小的优化获得的。

假设Acceptor收到提议值编号为n的Prepare请求信息,但是它已经回复了提议编号值大于n的其它的Prepare请求,从而承诺不接受任何编号为n的新提议。这样,Acceptor就没有理由响应新的Prepare请求,因为它不会接受提议者要发布的提议编号值为n的提议。因此,我们可以让Acceptor忽略这样的Prepare请求信息。我们也可以让Acceptor忽略它已经接受过的提议的Prepare请求信息,就是说,相同提议编号值的Prepare请求信息可以只回复一次而忽略后面重复请求信息。

通过这种优化,Acceptor只需要记住它曾经接受过的提议编号值最高的提议和它已响应的提议编号值最高的Prepare请求的提议编号值。因为无论失败与否都必须使P2c保持不变,所以即使失败,Acceptor也必须记住此信息,然后重新启动。请注意,只要Proposer从不尝试发布具有相同提议编号值的其他提议,它总是可以放弃该提议并将其遗忘。

将Proposer和Acceptor的行动放在一起,我们可以看到该算法分为以下两个阶段。

Phase 1.

(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors.

(b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded, then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered proposal (if any) that it has accepted.

Phase 2.

(a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n with a value v, where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals.

(b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n.

阶段一

(a)一个Proposer选择一个提议编号值n并向大多数的Acceptor发送带有这个提议编号值n的prepare请求信息;

(b)如果一个Acceptor接收到了一个带有提议编号值为n的prepare请求信息,而且n是这个Acceptor所回复的所有的prepare请求信息中携带的提议编号值最大的,那么这个Acceptor将会回复这个Proposer,回复信息中携带者promise(promise的内容是:这个Acceptor将不会接受其它提议编号值小于n的提议,提议包括promise请求信息和accept请求信息,而且这个Acceptor将记录提议编号值最大的那个编号以及与该提议编号值打包的提议值(如果这个Acceptor接收过这样的信息))。

阶段二

(a)如果一个Proposer接收到来自大多数Acceptor的回复信息(回复信息是针对该Proposer的提议编号值为n的),那么这个Proposer将继续向这些Acceptor发送提议编号值为n,提议值为v的accept请求信息。这里的v是Acceptor回复信息中携带的,或者,如果所有的Acceptor的回复消息都没有关于提议值的信息,那么v可以是该Proposer提出的任意值。

(b)如果当一个Acceptor接收到来自Proposer的accept请求信息时这个Acceptor没有接受提议编号值大于n的其它的提议(包括prepare请求信息或accept请求信息),那么这个Acceptor将接收这个请求信息,即接收该Proposer的提议(具体来说就是提议值v);否则,这个Acceptor不会接受这个Proposer的提议值。

一个Proposer可以提出多个提议,只要它遵循每个提议的算法即可。它可以随时在协议中间放弃提案(即使提案的请求信息和/或回复信息可能在提案被放弃后很长时间到达目的地,也保持了正确性。)。如果某些Proposer已开始尝试发布数量更大的提案,则放弃提案可能是一个好主意。因此,如果Acceptor因为已经收到了提议编号值较大的prepare请求信息而忽略了prepare或accept请求信息,则它可能应该通知Proposer,然后由谁放弃提议。这杨的性能优化不影响协议的正确性。

2.3 学习一个被选中的Value

要想学习一个已经被选中的value,Learner必须找出建议已被大多数Acceptor接受的提议。显而易见,让每个Acceptor在接受一个提议时向所有Learner做出回复,将其所接受的提议发送给所有的Learner。这使Learner能够尽快发现被选中的提议值,但它要求每个Acceptor对每个Learner做出回复-回复信息的数量等于Acceptor数量与Learner数量的乘积。

非拜占庭式失败的假设使一个Learner很容易从另一个Learner那里发现一个已经被接受的提议值。我们可以在一个Acceptor接受一个提议后向一个主要的Learner汇报这样的提议,该Learner又会通知其他Learner。这种方法需要所有Learner进行额外的一轮消息传递才能学习到新接受的提议。者也不太可靠,因为主要的Learner可能会失败。但是,它需要的回复消息数量仅等于Acceptor数量和Learner数量之和。

更一般而言,Acceptor可以回复一部分主要的Learner,然后每个主要的Learner都可以在通知所有其它的Learner。 使用更多的主要Learner可以提供更高的可靠性,但需要付出更大的通信复杂性。

由于消息丢失,可能会选择一个提议,而没有Learner会发现。Learner可以向Acceptor询问他们接受了哪些提议,但是一个Acceptor的失败可能使得Learner无法学习到是否大多数Acceptor已经接受了某个特定的提议。在这种情况下,Learner只有在选择进行提出新的提议时才能发现什么提议被接受了。如果Learner需要知道是否选择了一个提议,则可以使用上述算法让Proposer发布提议。(这个方法就是说:党Learner想要学习已经被接受的提议时,Learner可以让其相应的Proposer发起一次新的提议申请,根据上面的协议算法,我们可知,Acceptor将会回复已经接受的提议,这样,这个Learner就能够学到已经被接受的提议。这里,这个Learner可以同时扮演Proposer的角色,或者Learner和对应的Proposer之间有特定的信息交换方法以保证Proposer得到的回复信息能够被Learner学习到)

2.4 算法的Progress(即保证算法能够按照预定的逻辑执行)

构造一个场景很容易,在该场景中,两个Proposer各自不断发布数量越来越多的提议序列,而从未被接受。Proposer p完成阶段1的提议编号值为n1(即p先发出prepare请求信息,携带提议编号值为n1)。然后,另一个Proposer q完成阶段1的提议编号值为n2> n1。Propose p的第2阶段的accept请求信息对提案n1的请求被忽略,因为Acceptor都承诺不接受任何少于n2的新提议。因此,Proposer p重新开始阶段1并发送新的prepare请求信息,以获得新的提议编号值n3> n2,这将导致Proposer q的阶段2的accept请求信息被Acceptor忽略。这样交叉的提议申请,不断被拒绝,使得算法进入了一种活锁的状态。

为了保证算法能够正确执行,必须选择某个特定的Proposer作为尝试发布提议的唯一Proposer。如果特定的Proposer可以与大多数Acceptor成功通信,并且使用的提议编号值大于已使用的提议编号值,那么这个Proposer的提议最终将能够被接受。通过放弃提议,并在得知某个提议具有更高提议编号值的请求后再试一次,特定的Proposer最终将选择足够高的提议编号值。

如果系统中足够的Proposer,Acceptor和通信网络正常工作,那么可以通过选举一个特定的Proposer来实现Liveness。Fischer,Lynch和Patterson [1]的著名结果表明,为了保证选举Proposer的可靠性,算法必须使用随机性或实时性,例如使用超时。但是,无论选举成功与否,都会确保算法的安全性(即Safety属性)。

2.5 算法实现

Paxos算法[5]假设一个系统是由一组进程组成的通信网络。在其共识算法中,每个过程都扮演着Proposer,Acceptor和Learner的角色。该算法选择一个Leader Process,该Leader Process扮演着特定Proposer和Learner的角色。Paxos共识算法正是上述算法,其中prepare请求信息和回复信息作为普通消息发送(以防止混淆,每个Proposer 的回复信息里面携带该Proposer的请求信息中携带的提议编号值)。这个算法中使用稳定的存储来保存Acceptor需要记住的信息,如最大的提议编号或已接受的提议值,以保证算法不受硬件故障影响。Acceptor在实际发送回复信息之前将其预期的回复记录在稳定的存储中。

剩下的就是描述一种机制,以确保不会发布两个具有相同编号的提议。不同的Proposer从不相交的数字集中选择他们的提议编号值,因此两个不同的Proposer从不发布具有相同提议编号值的提议。每个Proposer都记住(在稳定的存储中)它尝试发布的编号值最高的提议,并从其第一阶段开始使用比其已经使用过的任何提议编号值更高的编号值开始。

3 实现一个状态机

实现分布式系统的最简单的方式就是将系统中的所有的节点当成一个集合,这些节点通过向一个集中的服务器发送指令,有这个集中的服务器来控制指令执行。这个集中的服务器可以想象成一个存储着所有节点的有序指令序列的状态机,系统中的指令执行就按照状态机保存的指令序列进行。状态机有一个当前状态,状态机从指令序列中取出一个指令并执行,产生一个输出,形成了下一个状态。

因为集中的服务器很可能失效,导致系统不能运转,所以我们使用很多的这样的服务器来执行上述的状态机。如何让多个服务器能够像集中服务器一样工作?只要保证多个服务器中的状态机(即指令序列一样),就可以保证。这样就能够保证系统的可用性。

为了保证每个服务器中的指令序列相同,我们在每个服务器上都运行一个Paxos的算法实例,第i个被选中的Value就是系统中第i需要被执行的指令。在每个算法实例中,服务器都同时扮演Acceptor、Proposer和Learner这三个角色。

4 References

[1] Michael J. Fischer, Nancy Lynch, and Michael S. Paterson. Impossibility of distributed consensus with one faulty process. Journal of the ACM, 32(2):374–382, April 1985.

[2] Idit Keidar and Sergio Rajsbaum. On the cost of fault-tolerant consensus when there are no faults—a tutorial. TechnicalReport MIT-LCS-TR-821, Laboratory for Computer Science, Massachusetts Institute Technology, Cambridge, MA, 02139, May 2001. also published in SIGACT News 32(2) (June 2001).

[3] Leslie Lamport. The implementation of reliable distributed multiprocess systems. Computer Networks, 2:95–114, 1978.

[4] Leslie Lamport. Time, clocks, and the ordering of events in a distributed system. Communications of the ACM, 21(7):558–565, July 1978.

[5] Leslie Lamport. The part-time parliament. ACM Transactions on Computer Systems, 16(2):133–169, May 1998.


讨论

1.Paxos的目的是什么?

2.Paxos的适用场景有哪些?

3.Paxos中的活锁问题有哪些解决方案?

4.Acceptor为什么要保存提议编号值和提议值?

5.Paxos算法的提议值(即Value)怎么选?

6.Paxos的流程

Part 2:Re-visiting of Paxos Made Simple(再读Paxos算法)_第1张图片
Paxos算法的简易流程



下一篇:Part 3:Disk Paxos翻译

你可能感兴趣的:(Part 2:Re-visiting of Paxos Made Simple(再读Paxos算法))