Paxos設計思路解析

本文以《Paxos made simple》爲藍本,分析Leslie Lamport大神設計Paxos算法(適用於異步非拜占庭故障下的分佈式系統)的思路。

大神先從共識算法(Paxos算法是共識算法的一種)開始,首先介紹了一下共識算法是幹啥的:共識算法可以確保所有被提出的值中,只有一個值能被選中(chosen)。如果沒有值被提出,那麼沒有值會被選中。如果一個值被選中了,那麼進程應該可以學習(learn)這個被選中的值。簡單來說,就是確保只有一個值被選中。

知道了共識算法是幹哈的之後,對於共識算法,一般有兩個重要的特性

1. 安全性(Safety),要求如下:1)只有被提出的值纔可以被選中;2)只有一個值能被選中;3)除非值被選中了,否則進程不會知道它被選中了,即:進程只學習已經被選中的值;也就是,如果滿足這三點,我們稱共識算法滿足了安全性。

2.靈活性(liveness)。靈活性的目標是確保某個被提出的值最終可以被選中,並且如果一個值被選中,進程最終可以學習該值。

Paxos算法設計的過程實際上是想方設法盡力滿足這兩種特性的過程。據此,大神在設計Paxos算法中,設計了三種角色:

1.提出者,主要負責提出值

2.接受者,主要負責接受值,在確保一個值被選中的過程中,發揮重要作用

3.學習者,學習選中的值

其中,每個進程都可以同時扮演這三種角色。具體每種角色會做什麼,接下來會詳細介紹。

至此,是一些Paxos算法設計的背景介紹。接下來,大神首先從安全性出發,嘗試使Paxos算法可以滿足安全性。


首先,1)只有被提出的值纔可以被選中,不難滿足,只要讓所有的進程只處理提出者提出的值,嘗試令其選中,即可滿足。

但是,2)只有一個值能被選中,是設計的難點。想一下,有很多值可以被提出,兩個不同的進程選擇了不同的值這一事件很有可能發生,那麼,如何才能確保一個值被選中呢?

最簡單的方法是隻有單個接受者。提出者發送一個提議(proposal,包含一個值)給接受者,接受者接受第一個被提出的值,默認接受者接受的第一個值被選中即可。但是,這樣的系統是很脆弱的,在接受者故障之後,整個系統就無法再選中值,喪失了靈活性。

因此,設置多個接受者是提升系統可用性的重要法寶。但是如何讓多個接受者達成共識,只選中一個值呢?Paxos算法的初步設想是,如果多個接受者(假設一共有7個)中的大多數(這裏大多數是4個,比一半多即可)都接受了某個值,那麼,就可以說那個值被選中了。

如果想要值被選中,首先,接受者肯定要接受值,所以必須滿足

P1. 接受者必須接受它收到的第一個提議。

這個很容易理解,要是接受者不接受收到的第一個提議,那只有一個值被提出的情況下,就不會有選中的值了。

但是在有好幾個不同的值被提出的時候,不同的接受者接受的第一個提議可能不一樣,這種情況下,有可能無法產生大多數接受者都接受了某個相同的值,值就無法被選中了,怎麼辦呢?

根據P1以及大多數接受者都接受了某個值,該值就被選中的設想,要想有值被選中,那麼接受者肯定可以接受多個值

這樣也有風險啊,如果多個不同的值都被大多數接受者接受了,那就有多個不同的值被選中,就違反了安全性!腫麼辦?大伸想了一個辦法,接下來嘗試使Paxos算法滿足下列條件:

P2. 如果值爲v的提議被選中,那麼每一個被選中的更大提議號的提議的值均爲v。

這裏,爲了區分不同的提議,假設對每個提議按提出的順序從小到大進行編號。這樣,接受者可以接受多個值,確保有值可以被選中。一旦有值被選中,之後再選中的值都和第一次被選中的值一樣,這樣不就確保了只有一個值被選中。機智!

但是,怎麼樣才能確保每一個被選中的更大提議號的提議的值均爲v呢?

一個值被選中,前提是有接受者接受它,那麼在有值被選中之後,確保接受者接受的值都是選中的值,那麼之後被選中的值肯定和第一次被選中的值一樣,所以,只要滿足下述條件,肯定能滿足P2:

P2a. 如果值爲v的提議被選中,那麼接受者接受的每一個更大提議號的提議的值均爲v。

想象一下,在值爲v的提議被選中之後,有一個接受者加入接受者大家庭,這個時候,他收到了一個值爲q的提議,根據P1,他肯定會接受q,但是這樣違反了P2a!所以,還需進行進一步限制!

P2b. 如果值爲v的提議被選中了,那麼任何提出者提出的更高提議號的提議的值均爲v。

可以看出,如果滿足P2b,肯定可以滿足P2a,也就可以滿足P2,同時也不會違背P1,完美!

最關鍵的問題來了:如何滿足P2b呢?

 

 

 

爲了讓提出者總是能提出跟之前被選中的值相等的值,Paxos算法中提出的者提出值的算法如下

1. 提出者選擇一個新的提議號n,並給某個接受者集合中的每個接受者發送一個請求,要求其回覆

    1)承諾永遠不再接受提議號小於n的提議,並且

    2)回覆已經接受的提議號小於n的,最大提議號的提議(如果有的話)。

    將這樣的請求稱爲編號爲n的“準備”(prepare)請求。

2. 如果提出者從大多數接受者處收到“準備”請求的回覆,那麼它可以提出一個提議號爲n,值爲v的提議,其中,v或者是收到的回覆中具有最大提議號的提議的值,或者是提出者選中的任何值(如果接受者沒有回覆提議)。

根據上述算法,第一個提出者可以選擇任意值(此時之前沒有接受者接受者過值);第二個提出者或許可以提出任何值(接受者沒有回覆提議),或許只能提出第一個提出者提出的值(有接受者回復提議);第三個提出者或許可以提出任何值(接受者沒有回覆提議),或許提出第一個提出者提出的值(接受第一個提議的接受者回復了提議),或許提出第二個提出者提出的值(接受第二個提議的接受者回復了提議,注意到此時無論收到只接受第一個提議的接受者的回覆,始終提出第二個提出者提出的值,因爲v是收到的回覆中具有最大提議號的提議的值)......

但是,一旦有提議被選中,那麼算法步驟2中v肯定是被選中的值。因爲提出者需要從大多數接受者處收到“準備”請求的回覆。想象一下,剛剛有個提議被選中,肯定有大多數提出者都接受了該提議的值,那麼提出者收到的大多數接受者的回覆中,肯定包括接受剛剛被選中提議的接受者,因爲上一個大多數和這次的大多數至少有一個接受者是重複的(這也是設定當大多數接受者都接受一個值,那麼值就被選中的意義)。依次類推,以後提出的提議的值只能是v。

假設有一個很久之前提出的提議(具有較小的提議號k),因爲網絡傳輸速度的關係,過了很長時間纔到達接受者處,此時系統已經有很多之後的提議被提出了,如果接受者接受了提議號k的提議,那麼就會對提議號大於k的提議的值產生影響。因爲接受者回復的是已經接受的提議號小於n的,最大提議號的提議,如果k在n之前,在提議號爲n的提議提出之後再接受提議號爲k的提議,會對接受者的回覆產生影響,因此接受者還要承諾永遠不再接受提議號小於n的提議。

至此,成功地解決了確保只有一個值被選中的問題!最後還有一個問題:3)除非值被選中了,否則進程不會知道它被選中了,即:進程只學習已經被選中的值;如何讓進程學習已經被選中的值?

這裏簡單的方法是,接受者接受一個值之後,就廣播通知所有學習者,如果學習者收到大多數接受者都接受了一個一樣的值,那麼這個值就被選中啦~

至此,安全性問題被圓滿解決,誕生了一個Paxos算法的雛形:

階段1 (a)提出者選擇一個提議號n併發送附帶n的“準備”請求給大多數接受者。

          (b)如果接受者收到附帶n的“準備”請求,並且n大於它已經響應的任何“準備”請求,那麼會回覆請求,並承諾不會接受任何提議號比n小的提議,並且附帶它已經接受的最大提議號的提議(如果有的話)。

階段2 (a)如果提出者從大多數接受者處收到“準備”請求(附帶n)的回覆,那麼會發送提議號爲n,值爲v的提議的“接受”請求給某個大多數接受者的集合。其中,v是收到的回覆中提議號最大的提議的值,如果回覆中沒有任何提議,那麼v可以是任意值。

          (b)如果接受者收到提議號爲n的提議的“接受”請求,除非已經響應了編號大於n的“準備”請求,否則它會接受這個提議。

學習者:收到大多數接受者發送的接受相同請求的消息,即可學習該請求。


對於靈活性:確保某個被提出的值最終可以被選中,並且如果一個值被選中,進程最終可以學習該值。如果上述Paxos算法中,所有進程都是學習者,那麼如果一個值被選中,進程最終可以學習該值可以滿足(如果某個進程和某個接受者之間的通信鏈路有問題,進程也可以通過詢問其他學習者來學習選中的值)。

對於確保某個被提出的值最終可以被選中,上述Paxos算法可能做不到。想象一下,兩個提出者一直不斷地提出提議,提議號越來越大,沒有一個提議被選中:提出者p爲一個提議號n1完成了階段1。另一個提出者q接着爲提議號n2(n2>n1)完成了階段1。提出者p爲提議號n1的提議發出的階段2的“接受”請求被忽視了,因爲接受者承諾不去接受提議號小於n2的提議。所以,提出者p開始一個新的提議號n3(n3>n2)並完成了階段1,導致提出者q的階段2的“接受”請求被忽視了,以此類推。

爲了實現靈活性,Paxos算法一定要選擇一個特定的提出者唯一嘗試去提出提議。Fischer,Lynch和Paterson提出的著名的結論——FLP定理表明,選擇一個提出者的算法或者依賴隨機性或者依賴實時性——例如,通過使用超時。因此,Paxos算法無法完全保證靈活性。但是,無論選舉的成敗與否,始終能確保安全性(safety)。


上述就是Paxos算法的基本設計思路,在上述設計之上,還可以進行一些優化,這些優化,Leslie Lamport大神在《Paxos made simple》以及《The part-time parliament》中也有提到。這裏只對最原始,最純碎的Paxos算法設計進行了描述。從Paxos算法的設計思路可以看出,Paxos算法始終可以確保安全性,雖然靈活性無法確切保證,但是Paxos算法提供的安全性以及大多數情況下都可以滿足靈活性足以讓他成爲工業界共識算法的首選。

 

 

 

 

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