Paxos算法

1)問題描述

分佈式中有這麼一個疑難問題,客戶端向一個分佈式集羣的服務端發出一系列更新數據的消息,由於分佈式集羣中的各個服務端節點是互爲同步數據的,所以運行完客戶端這系列消息指令後各服務端節點的數據應該是一致的,但由於網絡或其他原因,各個服務端節點接收到消息的序列可能不一致,最後導致各節點的數據不一致。舉一個實例來說明這個問題,下面是客戶端與服務端的結構圖:

當client1、client2、client3分別發出消息指令A、B、C時,Server1~4由於網絡問題,接收到的消息序列就可能各不相同,這樣就可能由於消息序列的不同導致Server1~4上的數據不一致。對於這麼一個問題,在分佈式環境中很難通過像單機裏處理同步問題那麼簡單,而Paxos算法就是一種處理類似於以上數據不一致問題的方案。

2)算法本身

算法本身我就不進行完整的描述和推導,網上有大量的資料做了這個事情,但我學習以後感覺萊斯利·蘭伯特(Leslie Lamport,paxos算法的奠基人,此人現在在微軟研究院)的Paxos Made Simple 是學習paxos最好的文檔,它並沒有像大多數算法文檔那樣搞一堆公式和數學符號在那裏嚇唬人,而是用人類語言讓你搞清楚Paxos要解決什麼問題,是如何解決的。這裏也藉機抨擊一下那些學院派的研究者,要想讓別人認可你的成果,首先要學會怎樣讓大多數人樂於閱讀你的成果,而這個描述Paxos算法的文檔就是我們學習的榜樣。

言歸正傳,透過Paxos算法的各個步驟和約束,其實它就是一個分佈式的選舉算法,其目的就是要在一堆消息中通過選舉,使得消息的接收者或者執行者能達成一致,按照一致的消息順序來執行。其實,以最簡單的想法來看,爲了達到大夥執行相同序列的指令,完全可以通過串行來做,比如在分佈式環境前加上一個FIFO隊列來接收所有指令,然後所有服務節點按照隊列裏的順序來執行。這個方法當然可以解決一致性問題,但它不符合分佈式特性,如果這個隊列down掉或是不堪重負這麼辦?而Paxos的高明之處就在於允許各個client互不影響地向服務端發指令,大夥按照選舉的方式達成一致,這種方式具有分佈式特性,容錯性更好。

說到這個選舉算法本身,可以聯想一下現實社會中的選舉,一般說來都是得票者最多者獲勝,而Paxos算法是序列號更高者獲勝,並且當嘗試提交指令者被拒絕時(說明它的指令所佔有的序列號不是最高),它會重新以一個更好的序列參與再次選舉,通過各個提交者不斷參與選舉的方式,達到選出大夥公認的一個序列的目的。也正是因爲有這個不斷參與選舉的過程,所以Paxos規定了三種角色(proposer,acceptor,和 learner)和兩個階段(accept和learn),三種角色的具體職責和兩個階段的具體過程就見Paxos Made Simple ,另外一個國內的哥們寫了個不錯的PPT ,還通過動畫描述了paxos運行的過程。不過還是那句話不要一開始就陷入算法的細節中,一定要多想想設計這些遊戲規則的初衷是什麼。

Paxos算法的最大優點在於它的限制比較少,它允許各個角色在各個階段的失敗和重複執行,這也是分佈式環境下常有的事情,只要大夥按照規矩辦事即可,算法的本身保障了在錯誤發生時仍然得到一致的結果。

3)算法的實現

Paxos的實現有很多版本,最有名的就是google chubby ,不過看不了源碼。開源的實現可見libpaxos 。另外,ZooKeeper 也基於paxos解決數據一致性問題,也可以看看它是如果實現paxos的。

4)適用場景

弄清楚paxos的來龍去脈後,會發現它的適用場景非常多,Tim有篇blog《Paxos在大型系統中常見的應用場景》 專門談這個問題。我所見到的項目裏,naming service是運用Paxos最廣的領域,具體應用可參考ZooKeeper


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