paxos_made_simple

Problem

一些进程,可以发起提议一个值,一个一致性算法要保证这些值中只有一个被选定。如果没有提议,就不能有值被选定。选定之后可以learn到这个值。

acceptor、proposer之间是互相配合的关系而不是对立的。

paxos的推理过程不是必要的,而是通过不断加强条件找到一种实现方式,所以paxos不是唯一的一致性算法协议。

应用场景:

安全性: 只有提议的值被选定,只有一个被选定,只有值被选定后才能learn到。 可用性: 最终值能选出来。选出来的值最终能够被learn到。

通过消息进行交互,使用异步、非byzantine模型。 进程随时可能失败、重启、或操作缓慢 消息可能丢失、重复,但是不会毁坏。

选定一个值

最简单的方式是只有一个acceptor,acceptor用接收到的第一个proposer提议的值作为选定的值。虽然简单,但是却有单点问题,当acceptor失效的时候系统就执行不下去了。 所以自然地,我们来使用多个acceptor的模型。 一个提议者proposer向多个acceptor发送提议,acceptor可能接受这个提议,如何确定哪个提议值被选定呢,在一个acceptor最多接受一个提议的情况下,大于半数的acceptor接受的值被认为选定。

如果不考虑进程失效和消息丢失的情况,当只有一个proposer发出一个提议的情况下,我们还需要最终能够选定一个值。 我们可以进行一下需求加强 P1. acceptor必须接受它收到的第一个提议 但是这样会有一个问题,不同的proposer可能会同时发出不同的提议,导致没有一个提议被半数以上被接受。 结合P1和上面的问题,我们得到acceptor还需要接受更多的提议。我们用一个序号来标识提议,proposer发送提议时需要生成序号来标识,这样提议就拥有了提议号和提议的值。为了避免混乱,我们要求不同的提议拥有不同的序号。序号的生成有各种实现方式,我们这里只是假设存在这样一个发号器。当一个提议被大多数acceptor接受后,我们就说这个提议和提议的值被选定了。我们可以允许多个提议被选定,但是必须要保证这些提议的值是一样的。 通过引入提议号, P2. 如果一个有值v的提议被选定了,则每个更高序号的被接受的提议的值都是v。 因为序号是整体有序的,所以条件P2能够保证关键的安全性属性: 只有一个值能够被选定。 要被选定的话,提议需要至少被一个acceptor接受,所以我们可以继续加强P2 P2a. 如果一个值为v的提议被选定了,则每个更高序号的被接受的提议的值都是v。 我们现在还维护P1来确保至少有提议被选定。因为交互方式是异步的,可能出现当某个值被选定时还有一个acceptor c没有收到过任何提议。假设这个时候一个新的proposer突然醒过来了然后发起了一个更高序号的proposal并且值和选定的不一样。P1要求c接受这个提议,会违反P2a。为了同时保持P1和P2a需要加强P2a到: P2b. 如果一个值为v的提议被选定了,则每个任何Proposer发出的更高序号的提议的值必须为v。 因为一个提议必须要先发起之后才能被接受,这样P2b满足P2a,P2a又能满足P2。

下面就变成了如何满足P2b。 我们先看下P2b拥有哪些特性: 假设某个值为v序号为m的提议被选定了,那么对于任何n>m的提议的值都是v。

那么任何m到n-1之间的提议。 如果提议值m被选中了,则必定存在一个包含大多数acceptor的集合C,其中每个acceptor都接受了它。 意味着,集合C内的每个acceptor都接受了m到n-1之间的提议,m到n-1之间的提议的值都是v。 因为任何包含大多数acceptor的集合S和集合C都有并集,所以可以通过加强P2b来实现提议n的值也是v。 P2c. 对于任意的v和n, 如果一个序号为n、值为v的提议被提出了,存在一个包含大多数acceptor的集合S使得如下两个条件至少满足一个 a) S中没有acceptor接受过任何序号小于n的提议 b) v是S中已经接受过的序号小于n的提议中序号最大的提议的值。

通过P2c可以推出P2b。 为了维护P2c的不变性条件,proposer想要提出序号为n的提议,必须知道acceptor接受过或将要接受的序号小于n的提议的最大提议的值。 获得一个已经接受过的提议的值是很简单的,但是预测将来的接受是非常难的。与其尝试预测未来,proposer可以通过要求一个将来不会有这种接受情况来控制。 换句话说,proposer要求acceptor们不能再接受序号小于n的提议了。这样就可以得到如下的发起提议的算法。

  1. proposer可以选择一个序号n,然后发送给acceptor的一个子集合,要求它们回答: a) 许诺不会接受序号小于n的提议 b) 已经接受过的提议中的序号小于n的最大序号的值,如果有的话 这个阶段成为prepare阶段
  2. 如果proposer收到了acceptor中大多数的回复,这样它就可以使用序号n和值v来发起提议了,v是这些回复中序号最大的提议的值,或者没有回复任何提议值时这个proposer可以自由选择提议值。 proposer向acceptor中的一些子集发送请求,要求接受这个提议。(这个子集不必和prepare阶段的一致)。这个请求称为accept请求。 上面介绍了proposer的算法,那么acceptor呢?acceptor可以从proposer收到两种请求: prepare和accept请求。acceptor可以忽略任何一个请求而不会危害到安全性。 所以我们只需要关心什么时候回复一个请求。acceptor总是可以回复prepare请求,在不违反许诺的情况下可以回复accept请求。 P1a. acceptor可以接受一个序号为n的提议,如果它没有答应过别人不这样做的情况。 P1a可以推出P1。

假设acceptor已经收到了一个序号为n的prepare请求,但是它已经回复过一个序号大于n的prepare请求了,也就是许诺不会接受任何新的序号为n的提议了。这样,就不必回复这个prepare请求了,忽略即可。我们还可以忽略已经接受过的提议的prepare请求。 这样,acceptor只需要记住它接受过的最大序号的提议和它回复过的序号最大的prepare请求。因为P2c在生效的情况下也要保持,所以acceptor必须要在实现和重启后依然能够记住它的这些信息。proposer可以放弃一个提议,只要不再使用相同的序号发送提议。

所以这个算法操作包含两个过程。 过程1. a) 一个proposer选择一个提议序号n然后给acceptor的大多数集合发送prepare请求。 b) 如果acceptor收到了一个序号为n的prepare请求,并且n大于它回复过的所有prepare请求,则它会许诺不再接受序号小于n的提议,并且返回已经接受过的最大序号的提议(如果有的话) 过程2. a) 如果proposer从acceptor中的大多数中收到了prepare请求(序号n)的回复,则它会给这些acceptor发送accept请求,请求中为序号为n和值为v的提议,v是恢复中序号最大的提议的值(或者没有提议的情况下可以是任意值) b) 如果acceptor收到了序号为n的accept请求, 则它会接受这个提议,除非它已经恢复了一个序号大于n的提议的prepare请求。

为了获得已经选定的值,learner必须找出被大多数acceptor接收的值。一种显然的算法就是每个leaner遍历所有的acceptor来得到哪个值被选定了。另一种方式是从leader中选出一个来遍历获取然后通知其他人。

liveness: 可能出现如下的类似活锁的情况,Proposer p使用提议序号n1完成了阶段1,另一个proposer q然后用大于n1的n2完成了阶段1,p在阶段2的acceptor请求被acceptor忽略掉了,因为acceptor许诺过不会接受任何序号小于n2的提议,然后p又开始用n3>n2来完成阶段1,导致q的阶段2被忽略,这样如此反复。 为了保证进度,要选择一个唯一的proposer来作为唯一的发起提议的proposal,可以通过选举来得到这个唯一的Proposer。

实现状态机 实现分布式系统的一种简单的方式就是让许多客户端发送命令给一个中央server,这个server是接收执行客户端请求的确定状态机。状态机有当前状态,然后通过执行命令产生一个输出并达到下一个状态。例如分布式银行系统的客户端是出纳员,状态机可以是包含所有用户的账户余额,一个取款操作就是在余额大于取款金额的情况下减少这个账户的余额。只有一个中央server的实现在server失效的情况下也失效了。所以我们使用一些server,每个server都独立的实现这个状态机,因为状态机是确定的,所以所有的初始状态相同的server只要接受相同序列的命令,都会产生相同序列的状态和输出。为了保证所有的server执行相同序列的状态机命令,我们把确定每个命令作为单独的paxos算法示例。 正常情况下,一个单独的server被选举为leader,来作为proposer,客户端发送命令给leader,leader决定这些命令的顺序。

转载于:https://my.oschina.net/u/1584569/blog/1790222

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值