paxos 分布式一致性算法

问题描述
假设有- -组可以提出提案的进程集合,那么对于一个一致性算法来说需要保证以下几点:
●在这些被提出的提案中,只有一个会被选定。
●如果没有提案被提出,那么就不会有被选定的提案。
●当一个提案被选定后,进程应该可以获取被选定的提案信息。

对于一致性来说,安全性(Safety) 往9需求如下:
●只有被提出的提案才能被选定(Chosen)。
●只能有一个值被选定。
●如果某个进程认为某个提案被选定了,那么这个提案必须是真的被选定的那个。
在对Paxos 算法的讲解过程中,我们不去精确地定义其活性(Liveness) 需求,从整体上来说,Paxos算法的目标就是要保证最终有一一个提案会被选定,当提案被选定后,进程最终也能获取到被选定的提案。

在该一致性算法中,有三种参与角色,我们用Proposer. Acceptor 和Learner来表示。
在具体的实现中,一个进程可能充当不止一种角色,在这里我们并不关心进程如何映射到各种角色。假设不同参与者之间可以通过收发消息来进行通信,那么:
●每个参与者以任意的速度执行,可能会因为出错而停止,也可能会重启。同时,即使一个提案被选定后,所有的参与者也都有可能失败或重启,因此除非那些失败或重启的参与者可以记录某些信息,否则将无法确定最终的值。
●消息在传输过程中可能会出现不可预知的延迟,也可能会重复或丢失,但是消息不会被损坏,即消息内容不会被篡改(拜 占庭式的问题#1)。

提案的选定
  要选定一个唯--提案的最简单方式莫过于只允许一个Accpetor存在,这样的话,Proposer只能发送提案给该Accpetor,Acceptor会选择它接收到的第一.个提案作为被选定的提案。这种解决方式尽管实现起来非常简单,但是却很难让人满意,因为一旦这个Accpetor出现问题,那么整个系统就无法工作了。
  因此,应该寻找一种更好的解决方式,例如可以使用多个Accpetor 来避免Accpetor的单点问题。现在我们就来看看,在存在多个Acceptor的情况下,如何进行提案的选取:
  Proposer向一个Acceptor集合发送提案,同样,集合中的每个Acceptor都可能会批准(Accept)该提案,当有足够多的Acceptor批准这个提案的时候,我们就可以认为该提案被选定了。那么,什么是足够多呢?我们假定足够多的Acceptor是整个Acceptor集合的一一个子集,并且让这个集合大得可以包含Acceptor集合中的大多数成员,因为任意两个包含大多数Acceptor的子集至少有一个公共成员。另外我们再规定,每一个 Acceptor最多只能批准-一个提案,那么就能保证只有-一个提案被选定了。

算法证明:

分布式一致性的条件

p1:一个Acceptor必须批准它收到的第一个提案。

P2:如果编号为Mo、Value 值为Vo的提案(即[Mo,Vo])被选定了,那么所有比编号Mo更高的,且被选定的提案,其Value值必须也是Vo。

通过满足如下条件来满足P2:
P2a:如果编号为Mo、Value 值为V。的提案(即[Mo,Vo])被选定了,那么所
有比编号Mo更高的,且被Acceptor批准的提案,其Value值必须也是Vo。

要同时满足P1和P2a,需要对P2a进行如下强化:
P2b:如果一个提案[Mo,V]被选定后,那么之后任何Proposer产生的编号更
高的提案,其Value值都为Vo

通过保持P2c,我们就能够满足P2b :

P2c规定了每个Proposer如何产生-一个提案:对于产生的每个提案[Mn, Vn],需要满足如下条件:
存在一个由超过半数的Acceptor组成的集合S:
●要么S中没有Acceptor批准过编号小于M的任何提案。
●要么S中的所有Acceptor批准的所有编号小于Mn的提案中,编号最大的那个提案的Value值为Vn。

从P1到P2c的过程其实是对一系列条件的逐步加强,最后p2c可由归纳法证明;算法的实现也依赖于此条件

算法陈述.
综合前面讲解的内容,我们来对Paxos算法的提案选定过程进行--个陈述。结合Proposer
和Acceptor对提案的处理逻辑,就可以得到如下类似于两阶段提交的算法执行过程。
阶段一
1. Proposer 选择- - 个提案编号Mn,然后向Acceptor的某个超过半数的子集成员发送编号为Mn的Prepare请求。
2.如果一个Acceptor收到一个编号为M的Prepare请求,且编号Mn大于该Acceptor已经响应的所有Prepare请求的编号,那么它就会将它已经批准过的最大编号的提案作为响应反馈给Proposer,同时该Acceptor会承诺不会再批准任何编号小于Mn的提案。

阶段二

1.如果Proposer收到来自半数以上的Acceptor对于其发出的编号为M的Prepare请求的响应,那么它就会发送一个针对[Mn, Vn]提案的Accept请求给Acceptor。
注意,Vn的值就是收到的响应中编号最大的提案的值,如果响应中不包含任何提案,那么它就是任意值。
2.如果Acceptor收到这个针对[Mn,Vn]提案的Accept请求,只要该Acceptor尚未对编号大于Mn的Prepare请求做出响应,它就可以通过这个提案。

中间过程的处理:

Acceptor会忽略提案编号小于Mn的Prepare请求,同时,Acceptor也会忽略掉那些它已经批准过的提案的Prepare请求,并向Proposer反馈忽略响应,Proposer收到此忽略响应后,

于是再次进入阶段一并提出了一个编号为Mn+1的提案。

猜你喜欢

转载自www.cnblogs.com/handwrit2000/p/12654605.html