什麼是Paxos算法
Paxos算法是萊斯利·蘭伯特(Leslie Lamport,2014年圖靈獎獲得者,目前就職微軟研究院)於1990年提出的一種基於消息傳遞且具有高度容錯特性的一致性算法,是目前公認的解決分佈式一致性問題最有效的算法之一
Google Chubby的作者Mike Burrows說過這個世界上只有一種一致性算法,那就是Paxos,其它的算法都是殘次品。
Paxos算法有兩個比較明顯的缺點:1.難以理解 2.工程實現更難
Paxos算法還可以分爲Basic Paxos, Multi-Paxos以及變種ZAB和Raft,本文重點解析Basic Paxos算法
什麼是分佈式數據一致性問題
Basic Paxos解決的問題: n個節點的分佈式系統收到m個數據請求,最終有且僅有一個數據請求會被所有n個節點接受從而保持分佈式系統的數據一致性
Basic Paxos 算法解析
•第一階段(查詢提案權利)
1) 生成全局唯一且遞增的ProposalID n (爲了保證Proposal ID唯一和遞增性,可採用時間戳+Server ID生成)
2) Proposer向所有Acceptors廣播Prepare(n)請求;
3) Acceptor比較n和minProposal,如果n>minProposal,minProposal=n,並且將當前已經接受的提案acceptedProposal和 acceptedValue返回(如果沒有則返回null)
4) Proposer接收到過半數回覆後,如果發現有acceptedValue返回,將所有回覆中acceptedProposal最大的acceptedValue作爲本次提案的value,否則可以任意決定本次提案的value
•第二階段(發出提案請求)
5) Proposer廣播Accept (n,value) 到所有節點;
6) Acceptor比較n和minProposal,如果n>=minProposal,則acceptedProposal=minProposal=n,acceptedValue=value,返回;否則,返回minProposal。
6) Proposer接收到過半數請求後,如果發現有返回值result >n,表示有更新的提議,跳轉到1);否則value達成一致
直接要看懂上面的算法比較困難,用示例來解析Basic Paxos算法如下
存取款示例1–簡單的順序請求
存取款示例2–複雜的非順序請求
三軍問題示例
1.1支紅軍在山谷裏紮營,在周圍的山坡上駐紮着3支藍軍
2.紅軍比任意1支藍軍都要強大;如果1支藍軍單獨作戰,紅軍勝;如果2支或以上藍軍同時進攻,藍軍勝
3.三支藍軍需要同步他們的進攻時間;但他們惟一的通信媒介是派通信兵步行進入山谷,在那裏他們可能被俘虜,從而將信息丟失;或者爲了避免被俘虜,可能在山谷停留很長時間
4.每支藍軍的參謀負責提議進攻時間;每支藍軍需要將軍批准參謀提出的進攻時間;很明顯,1個參謀提出的進攻時間需要獲得至少2個將軍的批准纔有意義
問題:是否存在一個協議,能夠使得2支或以上的藍軍同步他們的進攻時間?
paxos算法抽象該問題的求解:
參謀是Proposer發出提案
將軍是Acceptor接受提案並且多個將軍達到數據一致性
- 參謀1查詢提案權利,派通信兵帶信給3個將軍,內容爲(編號1)
- 3個將軍收到參謀1的提議,由於之前還沒有保存任何編號,因此把(編號1)保存下來,避免遺忘;同時讓通信兵帶信回去
- 參謀1收到至少2個將軍的回覆,再次派通信兵帶信給3個將軍,內容爲(編號1,進攻時間1)
- 3個將軍收到參謀1的進攻方案,Accept (編號1,進攻時間1),避免遺忘;同時讓通信兵帶信回去
- 參謀1收到至少2個將軍的確認信息,確認進攻時間已經被2個以上軍隊接收
- 參謀2查詢提案權利,派通信兵帶信給3個將軍,內容爲(編號2)
- 3個將軍收到參謀2的提議,由於(編號2)比(編號1)大,因此把(編號2)保存下來,避免遺忘;又由於之前已經接受參謀1的提議,因此讓通信兵帶信回去,內容爲(編號1,進攻時間1)
- 參謀2收到至少2個將軍的回覆,由於回覆中帶來了已接受的參謀1的提議內容,參謀2確認已經滿足2支以上藍軍同步了進攻時間,因此不再提出新的進攻時間
- 參謀1發起提議,派通信兵帶信給3個將軍,內容爲(編號1)
- 3個將軍的情況:將軍1和將軍2收到參謀1的提議,將軍1和將軍2把(編號1)記錄下來,如果有其他參謀提出更小的編號,將被拒絕;同時讓通信兵帶信回去; 負責通知將軍3的通信兵被抓,因此將軍3沒收到參謀1的提議;
- 參謀2在同一時間也發起了提議,派通信兵帶信給3個將軍,內容爲(編號2)
- 3個將軍的情況: 將軍2和將軍3收到參謀2的提議,將軍2和將軍3把(編號2)記錄下來,如果有其他參謀提出更小的編號,將被拒絕;同時讓通信兵帶信回去’ 負責通知將軍1的通信兵被抓,因此將軍1沒收到參謀2的提議;
- 參謀1收到至少2個將軍的回覆,再次派通信兵帶信給有答覆的2個將軍,內容爲(編號1,進攻時間1)
- 2個將軍的情況: 將軍1收到了(編號1,進攻時間1),和自己保存的編號相同,因此把(編號1,進攻時間1)保存下來;同時讓通信兵帶信回去; 將軍2收到了(編號1,進攻時間1),由於(編號1)小於已經保存的(編號2),因此讓通信兵帶信回去
- 參謀2收到至少2個將軍的回覆,再次派通信兵帶信給有答覆的2個將軍,內容爲(編號2,進攻時間2)
- 2個將軍的情況: 將軍2收到了(編號2,進攻時間2),和自己保存的編號相同,因此把(編號2,進攻時間2)保存下來,同時讓通信兵帶信回去; 將軍3收到了(編號2,進攻時間2),和自己保存的編號相同,因此把(編號2,進攻時間2)保存下來,同時讓通信兵帶信回去
- 參謀2收到至少2個將軍的確認回覆,確認進攻時間已經被2支以上藍軍接受
- 參謀1只收到了1個將軍的確認,同時收到一個Reject所以參謀1重新發起提議,派通信兵帶信給3個將軍
- 3個將軍的情況: 將軍1收到參謀1的提議,由於(編號3)大於之前保存的(編號1),因此把(編號3)保存下來;由於將軍1已經接受參謀1前一次的提議,因此讓通信兵帶信回去,內容爲(編號1,進攻時間1);將軍2收到參謀1的提議,由於(編號3)大於之前保存的(編號2),因此把(編號3)保存下來;由於將軍2已經接受參謀2的提議,因此讓通信兵帶信回去,內容爲(編號2,進攻時間2); 負責通知將軍3的通信兵被抓,因此將軍3沒收到參謀1的提議;
- 參謀1收到了至少2個將軍的回覆,比較兩個回覆的編號大小,選擇大編號對應的進攻時間作爲最新的提議;參謀1再次派通信兵帶信給有答覆的2個將軍,內容爲(編號3,進攻時間2)
- 2個將軍的情況: 將軍1收到了(編號3,進攻時間2),和自己保存的編號相同,因此保存(編號3,進攻時間2),同時讓通信兵帶信回去,; 將軍2收到了(編號3,進攻時間2),和自己保存的編號相同,因此保存(編號3,進攻時間2),同時讓通信兵帶信回去
- 參謀1收到了至少2個將軍的確認信息,確認進攻時間已經被2支以上藍軍接受