從PAXOS到ZOOKEEPER分散式一致性原理與實踐--Paxos演算法

衣舞晨風發表於2017-06-12

##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演算法原理與推導
    這裡寫圖片描述

##7、通過選取主Proposer保證演算法活性
下圖來自:Paxos演算法原理與推導
這裡寫圖片描述

##8、Paxos圖解
這裡寫圖片描述

一個分散式演算法,有兩個最重要的屬性: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

相關文章