paxos算法

paxos算法

背景

  Paxos算法是萊斯利·蘭伯特(Leslie Lamport,就是 LaTeX 中的”La”,此人現在在微軟研究院)於1990年提出的一種基於消息傳遞的一致性算法。由於算法難以理解起初並沒有引起人們的重視,使Lamport在八年後重新發表到TOCS上[2]。即便如此paxos算法還是沒有得到重視,2001年Lamport用可讀性比較強的敘述性語言給出算法描述[3]。可見Lamport對paxos算法情有獨鍾。近幾年paxos算法的普遍使用也證明它在分佈式一致性算法中的重要地位。06年google的三篇論文初現“雲”的端倪,其中的chubby鎖服務使用paxos作爲chubby cell中的一致性算法,paxos的人氣從此一路狂飆。

什麼是paxos算法

  Paxos 算法是分佈式一致性算法用來解決一個分佈式系統如何就某個值(決議)達成一致的問題。一個典型的場景是,在一個分佈式數據庫系統中,如果各節點的初始狀態一致,每個節點都執行相同的操作序列,那麼他們最後能得到一個一致的狀態1。爲保證每個節點執行相同的命令序列,需要在每一條指令上執行一個”一致性算法”以保證每個節點看到的指令一致。

paxos幹啥的

  分佈式系統中一般是通過多副本來保證可靠性,而多個副本之間會存在數據不一致的情況。所以必須有一個一致性算法來保證數據的一致,描述如下:
  假如在分佈式系統中初始是各個節點的數據是一致的,每個節點都順序執行系列操作,然後每個節點最終的數據還是一致的。
  Paxos算法就是解決這種分佈式場景中的一致性問題。對於一般的開發人員來說,只需要知道paxos是一個分佈式選舉算法即可。多個節點之間存在兩種通訊模型:共享內存(Shared memory)、消息傳遞(Messages passing),Paxos是基於消息傳遞的通訊模型的。

paxos算法介紹

Paxos保證以下三點:
1. 只有被提出提案才能被選定;
2. 只有一個值被選定;
3. 如果某個進程認爲某個提案被選定了,那麼這個提案必須是真的被選定的那個。
該一致性算法中有三個角色,分別是:proposer,acceptor,learner。它們之間通過消息來通訊。

paxos算法的兩階段
prepare 階段:
  1. Proposer 選擇一個提案編號 n,然後向acceptor的某個超過半數的子成員發送編號爲n的 prepare 請求;
  2. Acceptor 收到 prepare 消息後,如果提案的編號n大於該acceptor已經回覆的所有 prepare 請求的編號,則 Acceptor 將自己上次已經批准的最大編號提案回覆給 Proposer,並承諾不再回復小於 n 的提案;

acceptor階段:
  1. 當一個 Proposer 收到了半數以上的 Acceptors 對 prepare 的回覆後,就進入批准階段。它要向回覆 prepare 請求的 Acceptors 發送 accept 請求,包括編號 n 和根據 prepare階段 決定的 value。這裏的value是所有響應中編號最大的提案的value(如果根據 prepare 沒有已經接受的 value,那麼它可以自由決定 value)。
  2. 在不違背自己向其他 Proposer 的承諾的前提下,Acceptor 收到 accept 請求後即接受這個請求。即如果acceptor收到這個針對n提案的accep請求,只要改acceptor尚未對編號大於n的prepare請求做出過響應,它就可以通過這個提案。

流程圖如下2
這裏寫圖片描述

具體實例
首先,給出proposer和acceptor的消息圖3
這裏寫圖片描述

針對上面提出的兩個階段,分別解釋:
prepare階段
1.
  每個server向proposer發送消息,表示自己要當leader,假設proposer收到消息的時間不一樣,順序是: proposer2 -> proposer1 -> proposer3,消息編號依次爲1、2、3。
  緊接着,proposer將消息發給acceptor中超過半數的子成員(這裏選擇兩個),如圖所示,proposer2向acceptor2和acceptor3發送編號爲1的消息,proposer1向acceptor1和accepto2發送編號爲2的消息,proposer3向acceptor2和acceptor3發送編號爲3的消息。
2.
  假設這時proposer1發送的消息先到達acceptor1和acceptor2,它們都沒有接收過請求,所以接收該請求並返回【2,null】給proposer1,同時承諾不再接受編號小於2的請求;
  緊接着,proposer2的消息到達acceptor2和acceptor3,acceptor3沒有接受過請求,所以返回proposer2 【1,null】,並承諾不再接受編號小於1的消息。而acceptor2已經接受proposer1的請求並承諾不再接收編號小於2的請求,所以acceptor2拒絕proposer2的請求;
  最後,proposer3的消息到達acceptor2和acceptor3,它們都接受過提議,但編號3的消息大於acceptor2已接受的2和acceptor3已接受的1,所以他們都接受該提議,並返回proposer3 【3,null】;
  此時,proposer2沒有收到過半的回覆,所以重新取得編號4,併發送給acceptor2和acceptor3,此時編號4大於它們已接受的提案編號3,所以接受該提案,並返回proposer2 【4,null】。

accept階段
1
  Proposer3收到半數以上(兩個)的回覆,並且返回的value爲null,所以,proposer3提交了【3,server3】的提案。
  Proposer1也收到過半回覆,返回的value爲null,所以proposer1提交了【2,server1】的提案。
  Proposer2也收到過半回覆,返回的value爲null,所以proposer2提交了【4,server2】的提案。
2
  Acceptor1和acceptor2接收到proposer1的提案【2,server1】,acceptor1通過該請求,acceptor2承諾不再接受編號小於4的提案,所以拒絕;
  Acceptor2和acceptor3接收到proposer2的提案【4,server2】,都通過該提案;
  Acceptor2和acceptor3接收到proposer3的提案【3,server3】,它們都承諾不再接受編號小於4的提案,所以都拒絕。
  此時,過半的acceptor(acceptor2和acceptor3)都接受了提案【4,server2】,learner感知到提案的通過,learner開始學習提案,所以server2成爲最終的leader。

一些不錯的參考資料
lamport的兩篇論文:
Lamport, The part-time parliament, ACM Transactions on Computer Systems 16(2):133-169, 1998
Lamport, Paxos made simple, SIGACT News 32(4):18-25, 2001.
其他:
http://chuansong.me/n/1050231
http://www.cnblogs.com/ychellboy/archive/2009/12/29/1634801.html

zookeeper的選舉機制(zk的數據一致性核心算法paxos)

以一個簡單的例子來說明整個選舉的過程.
假設有五臺服務器組成的zookeeper集羣,它們的id從1-5,同時它們都是最新啓動的,也就是沒有歷史數據,在存放數據量這一點上,都是一樣的.假設這些服務器依序啓動,來看看會發生什麼.
1) 服務器1啓動,此時只有它一臺服務器啓動了,它發出去的報沒有任何響應,所以它的選舉狀態一直是LOOKING狀態
2) 服務器2啓動,它與最開始啓動的服務器1進行通信,互相交換自己的選舉結果,由於兩者都沒有歷史數據,所以id值較大的服務器2勝出,但是由於沒有達到超過半數以上的服務器都同意選舉它(這個例子中的半數以上是3),所以服務器1,2還是繼續保持LOOKING狀態.
3) 服務器3啓動,根據前面的理論分析,服務器3成爲服務器1,2,3中的老大,而與上面不同的是,此時有三臺服務器選舉了它,所以它成爲了這次選舉的leader.
4) 服務器4啓動,根據前面的分析,理論上服務器4應該是服務器1,2,3,4中最大的,但是由於前面已經有半數以上的服務器選舉了服務器3,所以它只能接收當小弟的命了.
5) 服務器5啓動,同4一樣,當小弟.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章