分佈式理論(五) - 一致性算法Paxos

前言

世界上只有一種一致性算法,就是 Paxos。出自一位 Google 大神之口。Paxos 也是出名的 晦澀難懂,推理過程極其複雜。算法

Paxos 有點相似以前說的 2PC3PC,可是解決了這兩種算法各類硬傷。該算法在不少大廠都獲得了工程實踐,好比阿里的 OceanBase分佈式數據庫,底層就是使用的 Paxos 算法。再好比 Googlechubby 分佈式鎖 也是用的這個算法。可見該算法在分佈式系統中的地位,甚至於,Paxos 就是 分佈式一致性 的代名詞。數據庫

正文

1. Paxos算法是什麼

Paxos 算法是 基於消息傳遞 且具備 高效容錯特性 的一致性算法,目前公認的解決 分佈式一致性問題 最有效的算法之一.編程

2. Paxos算法產生背景

2.1. 拜占庭將軍問題

拜占庭是古代東羅馬帝國的首都,因爲地域寬廣,守衛邊境的多個將軍(系統中的多個節點)須要經過信使來傳遞消息,達成某些一致的決定。但因爲信使中可能存在叛徒(系統中節點出錯),這些叛徒將努力向不一樣的將軍發送不一樣的消息,試圖會干擾一致性的達成。後端

2.2. Paxos算法由來

故事背景是古希臘 Paxos 島上的多個法官在一個大廳內對一個議案進行表決,如何達成統一的結果。他們之間經過服務人員來傳遞紙條,但法官可能離開或進入大廳,服務人員可能偷懶去睡覺。緩存

2.3 產生背景

在常見的 分佈式系統 中,總會發生 節點宕機網絡異常 (包括消息的 重複丟失延遲亂序網絡分區) 等狀況。安全

Paxos 算法主要就是解決如何在一個 發生如上故障 的分佈式系統中,快速正確的在集羣內 對某個值達成一致,而且保證 整個系統的一致性網絡

3. 算法詳解

3.1 角色 & 提案

提案 (Proposal)

注意:提案的範圍>value.後面會講到,[提案=編號+Value].也可表示爲[M,V]. 如下描述中暫定: 提案=P,Value=V.多線程

角色

  1. Proposer : Proposer 能夠 提出提案 (Proposal)。架構

  2. Accecptor : Acceptor 能夠 接受提案。一旦接受提案,提案 裏面的 value 值就被選定了。框架

  3. Learner : Acceptor 告訴 Learner 哪一個提案被選定了,那麼 Learner 就學習這個被選擇的 value

在具體的實現中,一個進程便可能是Proposer,也多是Acceptor,也多是Learner。

3.2. 問題描述

Paxos 算法的核心是 一致性。因此將從一致性問題的描述來說解該算法怎麼解決實際問題。

3.2.1. 一致性算法的前置條件

  1. 在被提出的 P 中,只有一個 V 被選中。
  2. 若是沒有 P 被提出,就沒有 V 被選中。
  3. P 被選定後,進程均可以學習被選中的 P

3.2.2. 不一樣角色經過發送消息進行通訊

  1. 每一個角色以任意的速度執行,可能因出錯而中止,也可能會重啓。一個 value 被選定後,全部的角色可能失敗而後重啓,除非那些失敗後重啓的角色能記錄某些信息,不然等他們重啓後沒法肯定被選定的值。

  2. 消息在傳遞過程當中可能出現 任意時長的延遲,可能會 重複,也可能 丟失,可是消息不會被 損壞

3.3. 推導過程

3.3.1. 只有一個Acceptor

一個 Acceptor 接受一個 P,那麼只有一個 V 被選定。

問題:若是這個 Acceptor 宕機,那麼整個系統服務不可用。

3.3.2. 多個Acceptor

問題:如何在多 Proposer 和多 Acceptor 狀況下,選定一個 value?

講解步驟分兩階段:約定 P1約定 P2

3.3.2.1. 約定P1

P1 :一個 Acceptor 必須接受一個它收到的第一個 P。

若是每一個 Proposer 會產生不一樣的 P,那麼多個 Proposer 一定產生多個 P,發給多個 Acceptor。根據 約定 P1Acceptor 分別接受到 P,就會致使不一樣的 V 被選定,以下圖所示:

如上圖所示,P1 會產生的問題: v1v2v3 都沒有被選定,由於他們只有被一個 Acceptor 接受。

對於上述問題,咱們須要一個額外的約定:

P1a : 一個提案 P 被選定,須要被半數以上 Acceptor 接受.

對於 P1a,其實就意味着 一個Acceptor必須接受不止一個提案

顯然,這與 P1 相矛盾,因此須要從新設計提案。原來的設計是: [提案P = value],如今從新設計 [提案P = 提案編號 + value],可表示爲 [M,V]

新問題:多提案被選定,如何保證被選定的提案 P 具備相同的value?

3.3.2.2. 約定P2

P2 : 若是提案 P[M0,V0] 被選定了,那麼全部比 M0 編號更高的,且被選定的 P,其 value 的值也是 V0。

對於 P2 中的 「被選定」:一個提案要被選定,首先至少要被一個 Acceptor 批准。所以,能夠理解 P2 爲:

P2a : 若是提案 P[M0,V0] 被選定了,那麼全部比 M0 編號更高的,且 [被Acceptor批准] 的P,其 value 值也是 V0。

只要知足 P2a,就能知足 P2多提案被選擇 的問題解決了,可是因爲 網絡不穩定 或者 宕機 的緣由(不可避免),會產生新問題:

假設有 5AcceptorProposer2 提出 [M1,V1]的提案,Acceptor2~5半數以上)均接受了該提案,因而對於 Acceptor2~5Proposer2 來說,它們都認爲 V1 被選定。Acceptor1 剛剛從 宕機狀態 恢復過來(以前 Acceptor1 沒有收到過任何提案),此時 Proposer1Acceptor1 發送了 [M2,V2] 的提案 (V2≠V1且M2>M1)。對於 Acceptor1 來說,這是它收到的 第一個提案。根據 P1(一個 Acceptor 必須接受它收到的 第一個提案),Acceptor1 必須接受該提案。同時 Acceptor1 認爲 V2 被選定。

這就出現了兩個問題:

  1. Acceptor1 認爲 V2 被選定,Acceptor2~5Proposer2 認爲 V1 被選定。出現了不一致

  2. V1 被選定了,可是 編號更高 的被 Acceptor1 接受的提案 [M2,V2]valueV2,且 V2≠V1。這就跟 P2a(若是某個 valuev的提案被選定了,那麼每一個 編號更高 的被 Acceptor 接受的提案的 value 必須也是 v矛盾了。

基於以上問題,全部就有了 P2b:

P2b : 若是 P[M0,V0] 被選定後,任何 Proposer 產生的 P,其值也是 V0。

對於 P2b 中的描述,怎樣保證 任何Proposer產生的P,其值也是V0 ?只要知足 P2c 便可:

P2c: 對於任意的 M、V,若是 [M,V] 被提出,那麼存在一個半數以上的 Acceptor 組成的組合 S,知足如下兩個條件中的任何一個: ① S 中沒有一個接受過編號小於 M 的提案。 ② S 中的 Acceptor 接受過的最大編號的提案的 value 爲 V。

推導完畢。。。

3.4. 算法流程

3.4.1. Proposer提出提案

整體思路以下:

(一). 學習階段:Prepare請求

Proposer 選擇一個新的提案 P[MN,?]Acceptor 集合 S(數目在半數以上)發送請求,要求 S 中的每個 Acceptor 作出以下響應:

  1. 若是 Acceptor 沒有接受過提案,則向 Proposer 保證 再也不接受編號小於N的提案

  2. 若是 Acceptor 接受過請求,則向 Proposer 返回 已經接受過的編號小於N的編號最大的提案

(二). 接受階段:Acceptor請求
  1. 若是 Proposer 收到 半數以上Acceptor 響應,則 生成編號爲 NvalueV 的提案 [MN,V]V 爲全部響應中 編號最大 的提案的 value

  2. 若是 Proposer 收到的響應中 沒有提案,那麼 valueProposer 本身生成,生成後將此提案發給 S,並指望 Acceptor 能接受此提案。

3.4.2. Acceptor接受提案

Acceptor 能夠忽略任何請求(包括 Prepare 請求和 Accept 請求)而不用擔憂破壞 算法的安全性。所以,咱們這裏要討論的是何時 Acceptor 能夠響應一個請求。

Acceptor 接受提案給出以下約束:

P1b:一個 Acceptor 只要還沒有響應過任何編號大於 N 的 Prepare 請求,那麼就能夠接受這個編號爲 N 的提案。

若是 Acceptor 收到一個編號爲 NPrepare 請求,在此以前它已經 響應過 編號大於 NPrepare 請求。根據 P1b,該 Acceptor 不可能接受編號爲 N 的提案。所以,該 Acceptor 能夠 忽略 編號爲 NPrepare 請求。固然,也能夠回覆一個 error,讓 Proposer 儘早知道本身的提案 不會被接受

所以,一個 Acceptor 只需記住:

  1. 已接受的編號最大的提案;
  2. 已響應的請求的最大編號。

4. Paxos算法描述

5. Learner學習提案

Learner 學習(獲取)被選定的 value 有以下三種方案:

6. 如何保證Paxos算法的活性

小結

Paxos節點宕機恢復消息無序或丟失網絡分化 的場景下能保證 數據的一致性。而 Paxos 的描述側重於 理論,在實際項目應用中,處理了 N 多實際細節後,可能已經變成了另一種算法,這時候正確性已經沒法獲得理論的保證。

要證實分佈式一致性算法的正確性一般比實現算法還困難。因此不少系統實際中使用的都是以 Paxos 理論 爲基礎而 衍生 出來的變種和簡化版。例如 GoogleChubbyMegaStoreSpanner 等系統,ZooKeeperZAB 協議,還有更加容易理解的 Raft 協議。

大部分系統都是靠在實踐中運行很長一段時間,通過驗證發現系統已能夠基本運行,沒有發現大的問題才能上生產環境。

相關連接

  1. 分佈式理論(一) - CAP定理
  2. 分佈式理論(二) - BASE理論
  3. 分佈式理論(三) - 2PC協議
  4. 分佈式理論(四) - 3PC協議
  5. 分佈式理論(五) - 一致性算法Paxos
  6. 分佈式理論(六) - 一致性協議Raft

歡迎關注公衆號: 零壹技術棧

image

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索