分佈式共識算法 (二) Paxos算法

 系列目錄

分佈式共識算法 (一) 背景html

分佈式共識算法 (二) Paxos算法算法

分佈式共識算法 (三) Raft算法數據庫

分佈式共識算法 (四) BTF算法promise

 1、背景

1.1 命名

Paxos,最先是Leslie Lamport 用Paxos島的故事模型進行描述,而得以命名。這位大神原來是學數學的,最終變成了計算機科學家,在2013年得到圖靈獎...附上美照:架構

1.2 Paxos問題

Paxos問題是指分佈式的系統中存在故障(crash fault),但不存在惡意(corrupt)節點的場景(即能消息丟失/重複,但無錯誤消息)下的共識達成問題。併發

1.3 Paxos協議

Paxos 協議是一個解決分佈式系統中,多個節點之間就某個值(提案)達成一致(決議)的通訊協議分佈式

1990年Leslie Lamport在論文《The Part-time Parliament》中提出Paxos共識算法,在工程角度實現了一種最大保障分佈式系統一致性的機制。Paxos算法被普遍應用在Chubby、ZooKeeper中。post

Paxos wiki:Paxos (computer science)
性能

2、Paxos算法

2.1 角色(核心就3個角色)

Client:客戶端,發起請求並等待返回。
Proposer案者):處理客戶端請求,將客戶端的請求發送到集羣中,以便決定這個值是否能夠被批准。
Acceptor(接受者):負責處理接收到的提議,他們的回覆就是一次投票。會存儲一些狀態來決定是否接收一個值。
Learner(學習者):當有同一個value的協議被超過一半的Acceptor採納併發送消息給Learner時,Learner採納該協議值。
Leader:一個特殊的Proposer。學習

2.2 Basic-Paxos算法

核心實現Paxos Instance主要包括兩個階段:

準備階段(prepare phase)和提議階段(accept phase)。細化爲4個小階段,wiki上是這樣描述的:

簡單來講,Basic Paxos 是一個經典兩階段提交(2PC)

第一階段

  • 1a prepare 準備: proposer向acceptors提出一個協議,這裏的協議就是指望的「一致性內容」
  • 1a promise 承諾: acceptor承諾只接收最大協議號的協議(包括prepare和accept),並拒絕比當前協議號N小的協議,回覆proposer以前接收的全部協議值。若是當前協議號N比以前都小,那麼回覆拒絕。

第二階段

  • 2a Accept Request 發起「accept」請求:proposer收到acceptor反饋的足夠的承諾後,給協議設最大值,若是沒回復,隨便設置一個值。發送"accept"請求給選定值的acceptors.
  • 2b Accepted: acceptor接受協議(該acceptor以前沒有承諾過大於該協議號的協議),並通知給proposer和learner.

    配上wiki流程圖以下:

其中prepare階段的做用,以下圖所示:

1.S1首先發起accept(1,red),並在S1,S2和S3達成多數派,red在S1,S2,S3上持久化
2.隨 後S5發起accept(5,blue),在S3,S4和S5達成多數派,blue在S3,S4和S5持久化
4.最後的結果是,S1和S2的值是red,而S4和S5的值是blue,s3存在異議,red覆蓋了blue?

解決方案:

  • 1.將提議進行排序,能夠爲每一個提議賦予一個惟一的ID,規定這個ID越大越新,很明顯(5,blue)和(1,red),5比1大,因此保留blue
  • 2.採用兩階段方法,拒絕舊提議

2.3 Muti-Paxos算法

不少文章有誤解說Muti-Paxos是一階段提交,那是僅限於leader穩定時。剛選出來一個新的leader時,依然是二階段提交以下圖:

 若是leader穩定不須要prepare和promise步驟,以下圖(圖中Proposer就是一個Leader):

Multi Paxos中leader用於避免活鎖(例如1個leader,4個Proposer,2個提議A,2個提議B不能達成一致,致使活鎖),但leader的存在會帶來其餘問題,一是如何選舉和保持惟一leader(雖然無leader或多leader不影響一致性,但影響決議進程progress),二是充當leader的節點會承擔更多壓力,如何均衡節點的負載。Mencius[1]提出節點輪流擔任leader,以達到均衡負載的目的;租約(lease)能夠幫助實現惟一leader,但leader故障狀況下可致使服務短時間不可用。

2.4 Muti-Paxos在google chubby中的應用

Google Chubby是一個高可用分佈式鎖服務,被設計成一個須要訪問中心化節點的分佈式鎖服務。本文只分析chubby服務端的實現。

 Chubby服務端的基本架構大體分爲三層

  ① 最底層是容錯日誌系統(Fault-Tolerant Log),經過Paxos算法可以保證集羣全部機器上的日誌徹底一致,同時具有較好的容錯性。

  ② 日誌層之上是Key-Value類型的容錯數據庫(Fault-Tolerant DB),其經過下層的日誌來保證一致性和容錯性。

  ③ 存儲層之上的就是Chubby對外提供的分佈式鎖服務和小文件存儲服務。

 

 Paxos算法用於保證集羣內各個副本節點的日誌可以保持一致,Chubby事務日誌(Transaction Log)中的每個Value對應Paxos算法中的一個Instance(對應Proposer),因爲Chubby須要對外提供不斷的服務,所以事務日誌會無限增加,因而在整個Chubby運行過程當中,會存在多個Paxos Instance,同時,Chubby會爲每一個Paxos Instance都按序分配一個全局惟一的Instance編號,並將其順序寫入到事務日誌中去。

  在Paxos中,每個Paxos Instance都須要進行一輪或多輪的Prepare->Promise->Propose->Accept這樣完整的二階段請求過程來完成對一個提議值的選定,爲了保證正確性的前提下儘量地提升算法運行性能,可讓多個Instance共用一套序號分配機制,並將Prepare->Promise合併爲一個階段。具體作法以下:

  ① 當某個副本節點經過選舉成爲Master後,就會使用新分配的編號N來廣播一個Prepare消息,該Prepare消息會被全部未達成一致的Instance和目前還未開始的Instance共用。

  ② 當Acceptor接收到Prepare消息後,必須對多個Instance同時作出迴應,這一般能夠經過將反饋信息封裝在一個數據包中來實現,假設最多容許K個Instance同時進行提議值的選定,那麼:

  -當前之多存在K個未達成一致的Instance,將這些未決的Instance各自最後接受的提議值封裝進一個數據包,並做爲Promise消息返回。

  -同時,判斷N是否大於當前Acceptor的highestPromisedNum值(當前已經接受的最大的提議編號值),若是大於,那麼就標記這些未決Instance和全部將來的Instance的highestPromisedNum的值爲N,這樣,這些未決Instance和全部將來Instance都不能再接受任何編號小於N的提議。

  ③ Master對全部未決Instance和全部將來Instance分別執行Propose->Accept階段的處理,若是Master可以一直穩定運行的話,那麼在接下來的算法運行過程當中,就再也不須要進行Prepare->Promise處理了。可是,一旦Master發現Acceptor返回了一個Reject消息,說明集羣中存在另外一個Master而且試圖使用更大的提議編號發送了Prepare消息,此時,當前Master就須要從新分配新的提議編號並再次進行Prepare->Promise階段的處理。

  可見chubby就是一個典型的Muti-Paxos算法應用,在Master穩定運行的狀況下,只須要使用同一個編號來依次執行每個Instance的Promise->Accept階段處理。

  

3、總結

Paxos算法的變種還有不少Cheap PaxosFast Paxos等等,本文介紹了使用最廣的Muti-Paxos算法。但願可以帶給你們一點分佈式一致性算法的入門靈感和思想。

 

 

====================

參考:

1.paxos的wiki:Paxos (computer science)

2.csdn博客:一步一步理解Paxos算法

3.書:《從Paxos到Zookeeper》

4.論文:《Time-Clocks-and-the-Ordering-of-Events-in-a-Distributed-System》

5.書:《區塊鏈 原理、設計與應用》

相關文章
相關標籤/搜索