分佈式共識算法 (一) 背景html
分佈式共識算法 (四) BTF算法promise
Paxos,最先是Leslie Lamport 用Paxos島的故事模型進行描述,而得以命名。這位大神原來是學數學的,最終變成了計算機科學家,在2013年得到圖靈獎...附上美照:架構
Paxos問題是指分佈式的系統中存在故障(crash fault),但不存在惡意(corrupt)節點的場景(即可能消息丟失/重複,但無錯誤消息)下的共識達成問題。併發
Paxos 協議是一個解決分佈式系統中,多個節點之間就某個值(提案)達成一致(決議)的通訊協議。分佈式
1990年Leslie Lamport在論文《The Part-time Parliament》中提出Paxos共識算法,在工程角度實現了一種最大保障分佈式系統一致性的機制。Paxos算法被普遍應用在Chubby、ZooKeeper中。post
Paxos wiki:Paxos (computer science)
性能
Client:客戶端,發起請求並等待返回。
Proposer(提案者):處理客戶端請求,將客戶端的請求發送到集羣中,以便決定這個值是否能夠被批准。
Acceptor(接受者):負責處理接收到的提議,他們的回覆就是一次投票。會存儲一些狀態來決定是否接收一個值。
Learner(學習者):當有同一個value的協議被超過一半的Acceptor採納併發送消息給Learner時,Learner採納該協議值。
Leader:一個特殊的Proposer。學習
核心實現Paxos Instance主要包括兩個階段:
準備階段(prepare phase)和提議階段(accept phase)。細化爲4個小階段,wiki上是這樣描述的:
簡單來講,Basic Paxos 是一個經典兩階段提交(2PC)
第一階段:
第二階段:
配上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?
解決方案:
不少文章有誤解說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故障狀況下可致使服務短時間不可用。
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階段處理。
Paxos算法的變種還有不少Cheap Paxos、Fast 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.書:《區塊鏈 原理、設計與應用》