Paxos算法

一、基本要求

1、拜占庭將軍問題

    拜占庭帝國有許多支軍隊,不同的將軍之間必須制定一個統一的行動計劃,從而做出進攻或者撤退的決定。同時,各個將軍在地理上都是被分隔開來的,只能依靠軍隊的通訊員來進行通訊。然而,在所有的通訊員中可能存在叛徒,這些叛徒可以任意篡改消息,從而達到欺騙將軍的目的。

2、要求

    假設有一組可以提出提案的進程集合,那麼對於一致性算法來說,需要保證以下幾點:

  1. 這些被提出的提案中,只有一個會被選定;
  2. 如果沒有提案被提出,那麼就不會有被選定的提案;
  3. 當一個提案被選定後,進程可以獲取被選定的提案的信息。

    分佈式算法有兩個重要的屬性:安全性和活性。安全性是指需要保證永遠都不會發生的事情,活性是最終一定會發生的事情。這裏不精確的去定義活性的需求,只討論安全性的要求:

  1. 只有被提出的提案才能被選定;
  2. 只有一個值能被選定;
  3. 如果某個進程認爲某個提案被選定了,那麼這個提案必須真的是被選定的。

3、角色

    在Paxos算法中,涉及到三種角色:Proposer、Acceptor和Learner。Proposer是提出提案的角色,Acceptor是判斷是否接受提案的角色。在算法實現的過程中,不同的進程可能充當不同的角色。假設不同的參與者之間可以通過收發消息來進行通信,那麼:

  1. 每個參與者以任意的速度執行,可能會因爲出錯而停止,也可能會重啓。同時,即使一個提案被選定後,所有的參與者也有可能會失敗或重啓,因此除非失敗或重啓的參與者可以記錄一些信息,否則將無法確定最終的值;
  2. 消息在傳播的過程中可能會出現不可預知的延遲,也可能會重複或丟失,但是消息不會被損毀,即消息內容不會被篡改(即拜占庭將軍問題)。

二、算法詳解

1、提案選定相關的兩個假設

    首先,確定一個基本概念,一個提案指的是[Mn, Vn],其中Mn是一個全局唯一的編號,而Vn是提案的值,即需要提交的內容本身。

    P1:一個Acceptor只要未響應過任何編號大於Mn的Prepare請求,那麼它就可以接受這個編號爲Mn的提案;

    P2:對於產生的每個提案,需要滿足:存在一個超過半數的Acceptor組成的集合S,要麼S中沒有Acceptor批准過編號小於Mn的任何提案,要麼S中所有的Acceptor批准的所有編號小於Mn的提案中,編號最大的那個提案的Value值爲Vn。

2、提案的生成

    根據上面的假設P2進行提案的生成。Proposer在產生一個編號爲Mn的提案時,必須要知道某一個將要或者已經被半數以上的Acceptor批准的編號小於Mn的最大的編號的提案,並且Proposer會要求Acceptor不再批准任何編號小於Mn的提案。

2.1 提案生成算法

    根據上面的要求,得到提案生成算法:

1、Proposer選擇一個新的提案編號Mn,然後向某個Acceptor集合的成員發送請求,要求該集合中的Acceptor做出如下回應:

  • 向Proposer承諾,保證不再批准任何編號小於Mn的提案;
  • 如果Acceptor已經批准過任何提案,就想Proposer反饋該提案的值。

    這個請求被稱爲:編號爲Mn的提案的Prepare請求。

2、根據Proposer收到的響應結果不同,有如下不同的Vn的處理方式:

  • 如果Proposer收到了來自半數以上的Acceptor的響應結果,那麼它就可以產生編號爲Mn、value爲Vn的提案,這裏的Vn是所有響應中編號最大的提案的Value值;
  • 如果Proposer收到的響應結果是半數以上的Acceptor都沒有批准過任何提案,即響應中不包含任何的天,那麼此時Vn的值可以由Proposer任意選擇。

2.2 Accept請求

    在確定提案之後,Proposer會將提案再次發送給某個Acceptor集合,並期望獲得它們的批准,這個請求被稱爲Accept請求。需要注意的是,此時接受Accept請求的Acceptor集合不一定是之前響應Prepare請求的Acceptor集合,但是任意兩個半數以上的Acceptor集合,必定包含至少一個公共Acceptor。

3、提案的批准

    可以得到兩階段提交算法:

階段一:

  1. Proposer選擇一個提案編號Mn,然後向Acceptor的某個超過半數的子集成員發送編號爲Mn的Prepare請求;
  2. 如果一個Acceptor收到一個編號爲Mn的Prepare請求,且編號Mn大於該Acceptor已經響應的所有Prepare請求的編號,那麼它就會將已經批准過的最大編號的提案作爲響應反饋給Proposer,同時該Acceptor會承諾不會再批准任何編號小於Mn的提案。

階段2:

  1. 如果Proposer收到來自半數以上的Acceptor對於其發出的編號爲Mn的Prepare請求的響應,那麼它就會發送一個針對[Mn, Vn]提案的Accept請求給Acceptor。需要注意的是,Vn的值就是收到的響應中編號最大的提案的值,如果響應中不包含任何提案,那麼它就是任意值;
  2. 如果Acceptor收到這個針對[Mn, Vn]提案的Accept請求,只要該Acceptor尚未對編號大於Mn的Prepare請求作出響應,它就可以通過這個提案。

4、提案的獲取

    上述三節已經討論瞭如何選定一個提案,這裏討論如何讓Learner獲取提案。

    所有的Acceptor將它們對提案的審批情況,統一發送給一個特定的Learner集合,該集合中的每個Learner都可以在一個提案被選定後通知所有其他的Learner這個Learner集合中的Learner個數越多,可靠性就越好,但同時網絡通信的複雜度也就越高。

5、選取主Proposer

    Proposer如果發現自己提議的編號過小導致被Acceptor拒絕,會獲取新的更大的編號並重發提議,這就可能導致出現兩個Proposer循環交替的不斷提出兩個提議的死循環。可以通過選定一個主Proposer,並規定只有主Proposer才能提出提議來避免這個問題。只要主Proposer和過半的Acceptor能進行正常的網絡通信,那麼但凡Proposer提出一個編號更高的提議都會被批准。

    通過選定一個主Proposer,可以保證算法的活性。

發佈了95 篇原創文章 · 獲贊 15 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章