Paxos演算法原理
Paxos演算法是圖靈獎獲得者提出的分散式系統一致性演算法。對於分散式系統來講,由於分散式系統具有多個節點,一旦涉及到修改資料並持久化儲存,最終必須達成資料的一致性,否則分散式系統就是錯誤混亂不可用的。
一 演算法的基本前提
這個演算法解決依賴於三個基本假設,即必須滿足這三個約束條件
• 只有一個值(value)被建議(proposed )的時候才可能被選擇(chosen), • 選擇只能選擇一個值, 並且 • 一個程序不能讀取這個選擇的值除非該值被確認。
關於第一條,也就是說不能節點自己提出建議值自己選擇,只通知選擇後的結果,因為這樣搞的話就退化成了一個建議,自我選擇對一致性是沒有意義的。
關於第二條,只能一個值,因為這是受一致性的約束,必須保證單機範圍的一致性,否則這個問題也就沒有意義。
第三條很容易理解,因為沒有確認的值也就沒有達成一致性,這與系統的一致性要求相悖。
從這個假設 我們看到一致性演算法劃分3個角色:提出建議值者(proposer),批准建議值者(acceptor)和接收值者(listener)表示。這些角色並不侷限於一個節點,也就是一個節點可以充當多個角色。
二 演算法的推導過程
提出建議就很簡單了,任何節點有需求時都可以廣播這個建議。
我們看選擇和接受值的過程,退化下這個問題,簡單的情形下,只有一個節點充當 批准建議者,這個時候只要讓接收的先後順序依次確認就行了,但是一旦這個節點失效,就會使得系統癱瘓陷入不可用狀態。
因此必須有多個批准節點,這種情況 選擇一個值 遵守 大多數協議,也就是大多數節點選擇了這個值,這個數多大呢,應該是至少為總數的一半+1,也就是n/2+1,因為這樣的話後續的修改就會有至少一個節點是相同的節點去處理一致性問題。假設不需要這個節點的話,如果是n/2,我們要把一個值由3修改為4,然後再4修改為5,第一次修改在n/2的節點達成一致,而第二次修改恰好在另外n/2達成一致,那麼這個修改就不可行,因為系統的這一半節點當前值不是4,而是3。如果強行修改為5的話,後續的讀取這個值就會正好一半節點認為是4,另一半節點認為是5,系統就會陷入兩難,只能隨機了,這樣系統就成了一個不穩定的錯誤系統。
這樣我們就有了一個必須滿足的約束條件
R1:大多數批准者(acceptor)接受了某個值後,該值才算被接受,即可以被接收值者讀到該值。
我們再退化下這個問題,假設只有一個建議被提出,那麼批准者(acceptor)必須選擇該值,因為批准者並不知道這是唯一的建議,只知道這是第一次接收到的建議,因此有第二個約束條件,作者標記為P1
P1 一個acceptor需要接受/同意其第一次收到的proposal中的value。
由R1約束條件的匯出我們知道必須有一個節點處理多個建議,由P1我們知道必須有建議的時序性,為了標記這個時序性,我們用數字編號大小記錄區分。
因此,一個proposal需要包含兩個元素:編號和value。(這裡將這個proposal表示為p<n,v> ,n表示編號,v表示value)。
為了保證不同的proposer提出的proposal上面的編號不一樣,需要特殊的機制來獲取編號,編號必須包含節點資訊以及節點本身提出的時序性(比如可以根據系統中的acceptor的數量n以及這個proposer的編號m,例如編號為m的proposer提出的proposal的編號變化方式為m+i*n,i是提出proposal的次數,即i>=0)。這時候R1就可以描述為一個value被接受的條件就是一個帶有該value的不同proposal被大多數的acceptor接受。這樣,我們就說這個value和該proposal被接受了。
這樣的話,我們必須允許多個proposal被系統所接受,這時我們需要保證所有的被選中的proposal裡面帶有的value是相同的,也就是說達成了一致性。
而這多個proposal不可避免的存在編號不同的問題,因為單個節點可以重複發起建議,後續時序的發起編號必然是大的編號,由於最先提出的約束第二條,只能批准一個值。因此我們得出了下面的約束條件:
P2:如果一個帶有某個value的proposal被選中,那麼所有的帶有較高編號的proposal中的值必須也是這個value。
也就是說
P2:一旦一個具有 value v 的提案被批准(chosen),那麼之後批准(chosen)的提案必須具有 value v。
批准一個 value 意味著多個 acceptor 接受(accept)了該 value。因此,可以對 P2 進行加強,推廣到所有acceptor 的情況:
P2a:如果一個帶有某個value的proposal被選中,那麼所有被acceptor接受的帶有較高編號的proposal中的值必須也是這個value。
P2b:如果一個帶有某個value的proposal被選中,那麼所有proposer提出的帶有較高編號的proposal中的值必須也是這個value。
P2b可以推出P2a,因為提出的都是這個value,接受的不可能有其他value。
P2c:如果一個編號為 n 的提案具有 value v,那麼存在一個多數派,要麼他們中所有人都沒有接受(accept)編號小於 n
的任何提案,要麼他們已經接受(accept)的所有編號小於 n 的提案中編號最大的那個提案具有 value v。
下面證明P2c可以推出P2b
對於所有編號小於n的任何提案沒有被接受的多數派,那麼通過提案的多數派必然和這個多數派必然有一個公共的acceptor,這時說明可以確保沒有任何提案被通過,所以我提案值不受任何約束。
對於已經接受編號小於n的最大編號m提案是value v的多數派,同理這個時候任意其他多數派和這個的公共acceptor不接受其他提案,那麼選出的值必然是這個多數派接受的值組成的集合中一員,如果不是value v,假設是u,
同時不是最大的的編號,假設編號為k,k<m,那麼編號k+1,..,m提出的值是u,得出u=v,矛盾,所以通過的提案必然是value v。
三 演算法的提出
要滿足P2c的約束,proposer提出一個提案前,首先要和足以形成多數派的acceptors進行通訊,獲得他們進行的最近一次接受(accept)的提案(prepare過程),之後根據回收的資訊決定這次提案的value,形成提案開始投票。當獲得多數acceptors接受(accept)後,提案獲得批准(chosen),由proposer將這個訊息告知learner。這個簡略的過程經過進一步細化後就形成了Paxos演算法。
在一個paxos例項中,每個提案需要有不同的編號,且編號間要存在全序關係。可以用多種方法實現這一點,例如將序數和proposer的名字拼接起來。如何做到這一點不在Paxos演算法討論的範圍之內。
如果一個沒有chosen過任何proposer提案的acceptor在prepare過程中回答了一個proposer針對提案n的問題,但是在開始對n進行投票前,又接受(accept)了編號小於n的另一個提案(例如n-1),如果n-1和n具有不同的value,這個投票就會違背P2c。因此在prepare過程中,acceptor進行的回答同時也應包含承諾:不會再接受(accept)編號小於n的提案。這是對P1的加強:
P1a:當且僅當acceptor沒有迴應過編號大於n的prepare請求時,acceptor接受(accept)編號為n的提案。
現在已經可以提出完整的演算法了。
通過一個決議分為兩個階段:
1.prepare階段:
1.proposer選擇一個提案編號n並將prepare請求傳送給acceptors中的一個多數派;
2.acceptor收到prepare訊息後,如果提案的編號大於它已經回覆的所有prepare訊息(回覆訊息表示接受accept),則acceptor將自己上次接受的提案回覆給proposer,並承諾不再回復小於n的提案;
2.批准階段:
1.當一個proposer收到了多數acceptors對prepare的回覆後,就進入批准階段。它要向回覆prepare請求的acceptors傳送accept請求,包括編號n和根據P2c決定的value(如果根據P2c沒有已經接受的value,那麼它可以自由決定value)。
2.在不違背自己向其他proposer的承諾的前提下,acceptor收到accept請求後即批准這個請求。
這個過程在任何時候中斷都可以保證正確性。例如如果一個proposer發現已經有其他proposers提出了編號更高的提案,則有必要中斷這個過程。因此為了優化,在上述prepare過程中,如果一個acceptor發現存在一個更高編號的提案,則需要通知proposer,提醒其中斷這次提案。
五 演算法的補充見解
演算法本質是通過大多數acceptor prepare階段獲取一個鎖,再達成一致前只能是可能的值v,如果有新的值v1要被建議只能是後續的時序。
與分散式事務的關係 分散式事務與演算法的目的相同,都是保證資料一致性。保證資料一致性本質上只有一個途徑,就是這個演算法提出的大多數投票達成共識,因此從這一點上看,其他演算法都是這個演算法的變種,而分散式事務本質上是這個演算法的事務概念的包裝實現。
演算法與分散式系統的關係 分散式系統的基本原理 CAP 必然滿足其中一條,這個演算法是一致性的保證的基石。演算法解決的是一致性問題,無論強一致性還是弱一致性都要保證最終的一致性,演算法是一致性的基礎。
參考資料:
https://blog.csdn.net/chao2016/article/details/81149674
https://zh.wikipedia.org/wiki/Paxos%E7%AE%97%E6%B3%95