从PAXOS到ZOOKEEPER分布式一致性原理与实践--Paxos算法

1、Paxos算法

算法中的参与者主要分为三个角色,同时每个参与者又可兼领多个角色:

  1. proposer 提出提案,提案信息包括提案编号和提议的value;
  2. acceptor 收到提案后可以接受(accept)提案;
  3. learner 只能"学习"被批准的提案;

一致性算法需要保证:

  1. 决议(value)只有在被proposers提出后才能被批准(未经批准的决议称为"提案(proposal)");
  2. 在一次Paxos算法的执行实例中,只批准(chosen)一个value;
  3. learners只能获得被批准(chosen)的value;

2、Proposer生成提案

     对于一个Proposer来说,获取那些已经被通过的提案远比预测未来可能会被通过的提案来的简单。因此,Proposer在产生一个编号为Mn的提案时,必须要知道当前某一个将要或已经被半数以上Acceptor批准的编号小于Mn但为最大编号的提案。并且,Proposer会要求所有的Acceptor都不要再批准任何编号小于Mn的提案了–这就引出了如下的提案生成算法。

     Proposer选择一个新的提案编号Mn,然后向某个Acceptor集合的成员发送请求,要求该集合的Acceptor做出如下回应:

  • 向Proposer承诺,保证不再批准任何编号小于Mn的提案。
  • 如果Acceptor已经批准过任何提案,那么其就向Proposer反馈当前该Acceptor已经批准过的编号小于Mn但为最大编号的那个提案的值。

     我们将该请求成为编号为Mn的提案的Prepare请求。

      如果Proposer收到了来自半数以上的Acceptor的响应结果,那么它就可以产生编号为Mn、Value值为Vn的提案,这里的Vn是所有相应中编号最大的提案的Value值。 当然还存在另一种情况,就是半数以上的Acceptor都没有批准过任何提案,即相应中不包含任何的提案,那么此时Vn值就可以由Proposer任意选择。

     在确定提案之后,Proposer就会将该提案再次发送给某个Acceptor集合,并期望获得它们的批准,我们称此请求为Accept请求。需要注意的一点是,此时接收Accept请求的Acceptor集合不一定是之前响应Prepare请求的Acceptor集合。

3、Acceptor批准提案

     在上文中,我们已经讲解了Paxos算法中Proposer的处理逻辑,下面我们来看看Acceptor是如何批准提案的。

     根据上面的内容,一个Acceptor可能会收到来自Proposer的两种请求,分别是Prepare请求和Accept请求,对这两类请求做出响应的条件分别如下:

  • Prepare请求:Acceptor可以在任何时候响应一个Prepare请求。
  • Accept请求:在不违背Accept现有承诺的前提下,可以任意相应Accept请求。

     因此,对Acceptor逻辑处理的约束条件,大体可以定义如下:

一个Acceptor只要尚未响应过任何编号大于Mn的Prepare请求,那么它一定就可以接收这个编号为Mn的提案。

同时,值得一提的是,Paxos算法允许Acceptor忽略任何请求而不用担心破坏其算法的安全性。

4、算法优化

     假设一个acceptor接收到一个编号为n的prepare请求,但是它已经回应了一个编号大于n的prepare请求。于是acceptor就没有必要回应这个prepare请求了,因为它不会批准这个编号为n的议案。它还可以忽略已经批准过的议案的prepare请求。

     有了这些优化,acceptor只需要保存它已经批准的最高编号的议案(包括编号和决议),以及它已经回应的所有prepare请求的最高编号。因为任何情况下,都需要保证P2C,acceptor必须记住这些信息,包括失效并重启之后。注意,proposer可以随意的抛弃一个议案——只要它永远不会使用相同的编号来提出另一个议案。

P2C:
对于任意的Mn和Vn,如果提案[Mn, Vn]被提出,那么肯定存在一个由半数以上的Acceptor组成的集合S,满足以下两个条件中的任意一个。
1、S中不存在任何批准过编号小于Mn的提案的Acceptor。
2、选取S中所有Acceptor批准的编号小于Mn的提案,其中编号最大的那个提案其Value值是Vn。

5、算法陈述

阶段一:

  1. p选择一个提案编号m,然后向a的某个超半数自己成员发送编号为m的prepare请求。
  2. 如果一个a收到一个编号为m的prepare请求,且编号m大于该a已经响应的所有prepare编号,那么他就会将他已经批准过的最大编号的提案(包含id和value)最为响应反馈给p,同时a承诺不会再批准任何编号小于m的提案。

阶段二:

  1. 如果p收到了来自半数以上a对于其发出的编号为m的prepare请求的响应,那么他就会发送一个针对[m,v]的提案的accept请求给a.
    注意,v的值就是收到的响应中编号最大的提案的值(有可能和自己提交的值不一致,是阶段一中a反馈给p的accept请求中的v值),如果响应中不包含任何提案,那么他可以是任意值。
  2. 如果a收到了这个[m,n]的请求,只要改a尚未对编号大于m的prepare请求作出响应,他就可以通过这个提案。

6、提案获取

下图来自:Paxos算法原理与推导
从PAXOS到ZOOKEEPER分布式一致性原理与实践--Paxos算法_第1张图片

7、通过选取主Proposer保证算法活性

下图来自:Paxos算法原理与推导
从PAXOS到ZOOKEEPER分布式一致性原理与实践--Paxos算法_第2张图片

8、Paxos图解

从PAXOS到ZOOKEEPER分布式一致性原理与实践--Paxos算法_第3张图片

一个分布式算法,有两个最重要的属性:Safety 和Liveness,简单来说:
Safety是指那些需要保证永远都不会发生的事情。
Liveness是指那些最终一定会发生的事情。

Paxos图解(xmid图解)下载:
http://download.csdn.net/detail/xunzaosiyecao/9867962

从PAXOS到ZOOKEEPER分布式一致性原理与实践pdf下载:
http://download.csdn.net/detail/xunzaosiyecao/9867618

推荐一篇文章:《生活中的Paxos,原来你我都在使用》

作者:jiankunking 出处:http://blog.csdn.net/jiankunking

你可能感兴趣的:(ZooKeeper,各类有趣算法)