whypaxos

爲什麼是paxos

最近又看了次 paxos made simple,每次看完總覺得理解了它,但不久之後又將它忘得一乾二淨,因此決定這次好好梳理下。本文還參考了微信對於paxos 的實現的相關文章(見 phxpaxos)。

本文主要從paxos是如何執行的,已經如果不這麼執行,會有什麼樣的問題來描述paxos,這個思路是我覺得比較好接受的方式。至於paxos的理論證明,在 The Part-Time Parliamentpaxos made simple 已經將的很清楚了,有興趣可以去看論文。

paxos基本定義

概論:paxos要解決的問題是,在多臺機器確定一個值。也就是說完整跑完paxos,可以保證在這個集羣裏,最終總有個時刻,所有存活的機器保留的這個值都相同(至於得到一個不變量,在工程上有什麼用,這裏就不加討論了)。

paxos裏面有幾個角色:

  • proposer:提議者,接收客戶端的請求,發起一個請求。
  • acceptor:接受者,決定是否接受proposer的提議。

對於一個提議,包含:

  • proposal number:提議號,全局唯一,且各自的機器需要保證自己的proposal number是遞增的。實現可以是:時間戳加ip或者提前分好各自的提議段(第一臺機子:1,101,201,第二臺機子:2,102,202)。
  • proposal value:提議的值。

paxos的執行流程

第一階段(prepare request)

  • proposer  選擇一個 proposal number ,然後將它發送給大多數 acceptor (大多數:對於一個固定集合來說,大多數基本就是大於一半的數量。更精確的定義的是,兩個大多數集總有一個共同元素)。這個請求被稱爲:prepare request 。
  • 對於 acceptor ,如果它收到一個 proposal number 爲 n 的 prepare request,那麼倘若這個 acceptor 沒有回覆過 proposal number 大於 n 的 prepare request ,則該 acceptor 需要回復這個 prepare request,並承諾不再 accept 任意 proposal number 小於 n 的 prepare request,如果在這之前該 acceptor accept 過任何 proposal,則還必須帶上 accept 過的擁有最大 proposal number 的 proposal (含 proposal number 和 value)。

第二階段(accept request)

  • 如果 proposer 收到大多數 acceptor 對於 proposal number 爲 n 的 prepare request 的響應,那麼該 proposer 就可以向 acceptor 發起 accept request,proposal number 爲 n,值爲 v (其中,如果 acceptor 響應中帶有 proposal,則 v 爲 proposal number 最大的那個 proposal 值,否則 v 可以爲任意值)
  • acceptor 收到 accept request 後,如果這個proposal 不違背該 acceptor 做出的承諾(在 prepare request 階段,不再接受 proposal number 小於 n 的承諾),則 acceptor 必須 accept 這個請求。

當大多數的 acceptor 都回應了這個 accept request,那麼完整的 paxos 就已經跑完了,唯一的一個值已經被choose了。

爲什麼paxos要這麼麻煩

不用兩個階段可以麼

paxos 的強大之處在於即使有多個 proposer 並行地提出請求,也能保證集羣最終只會 choose 到同一個值,而且只要集羣的大多數機器不宕機,服務是可以繼續下去的。

如果各個 proposer  直接提出 accept request ,那麼很容易就出現這樣的情況:有4臺機器ABCD,A和B提出了propose,很可能就出現了AC兩臺機器同意了A的請求,BD兩臺機器同意B的請求,最終將無法得到一個結果。

話雖這麼說,但 paxos 其實也會協商得不到一個值的情況:A向大多數機器發送了 prepare request,proposal number 爲 1,並得到了大多數機器的響應;與此同時 B 也向大多數機器發送了 prepare request ,proposal number 假設爲 2,那麼這時 A 再發送 accept request 的時候,就會被這些機器拒絕(它們已經承諾不接受proposal number 小於2 的請求),所以A 重新發送 prepare request , proposal number 爲101,之後 B 再來發送 accept request 的時候就被拒絕,所以 B 又發送proposal number 爲102的 prepare request,如此往復,就永遠得不到一個共同的值。

由於 paxos 存在着上述這種情況,所以如果有個 leader ,由這個 leader 來提出 propose ,就不會有上述的情況。那麼這個 leader 是怎麼確定的,在 paxos made simple 的論文裏面並沒有提到。不過可以看出,paxos 對這個 leader 並沒有做出任何限制,也就是說,即使在某個時刻存在着兩個 leader ,同樣也不會影響到 paxos 來確定出最終的一個值。因此 leader 的選舉就變得不是特別複雜,例如利用一些簡單的策略:一旦收到其他機器的 accept request ,就在一段隨機時間內,停止進行 paxos 的 prepare request。由於這是隨機時間,所以最終總會有臺機器脫穎而出,不斷進行 prepare request,然後 accept request ,這使得其他機器又進行一段時間的停止 prepare request,所以該機器又能順利通過 prepare request,再 accept request。這樣,一個 leader 就自然而然地產生了。

那 paxos 來選舉 master 又是怎麼回事

master 的一個重要特點是:集羣在任意時刻,最多只能有一個 master 。也就是說,寧可沒有 master ,也不能出現多個 master 的情況。說起 master ,要稍微說下 paxos 選出一個值後有什麼用,可以這麼想,paxos 可以選出一個值,那麼順序運行多個 paxos 實例,就可以做到在集羣中,各個機器都維護一個狀態機,順序執行 paxos 的結果可以作爲這個狀態機的輸入,那麼就能保證集羣中所有的狀態機都能得到一個最終一致性(這也就是基本的 multi-paxos 的模型)。而 master 的作用就體現出來了,如果有個 master 進行讀寫,那麼從這個 master 總能讀出最新的數據。

至於 master 怎麼選,簡單點說就是發起一個 paxos 的過程,各臺機器的proposal value 就是自己的節點信息,也就是各個機器都認爲自己是 master ,最終確定下來一個 value,也就確定了 master 。當然也沒這麼簡單,如果 master 掛了又該怎麼辦?其實不需要主動去判斷 master 是否掛了,只需要給 master 一個任期,任期結束後,master 主動去續約。只要 master 在任期結束前,提前去續約,就總是能續約成功的。 既然引入了任期的概念,也就是說,需要用多個 paxos 實例來確定,也即是 multi-paxos ,但有機器與 master 失聯,沒有學到 master 的續約的請求後,重新發起次 paxos,由於 paxos 實例落後於 master 的,自然不會得到大多數機器的接受,進而可以學到 master 是誰。

不同的 proposer 的 proposal number 一樣可以麼

不可以。paxos 對 proposal number 是有一定的要求的:proposal number 在所有機器中必須是唯一的,而且各自的機器必須是遞增的。從 paxos 的過程也可以看出,在 prepare request 階段,是隻利用 proposal number 來進行提議的,不需要用到提議的值,承諾也是針對 proposal number ,如果存在不同機器的 proposal number 是一樣的,而它們提議的值卻不一定一樣,這就違背了最終所有機器確定唯一的值的初衷了。

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