分佈式一致性協議介紹(Paxos、Raft)

 兩階段提交php

Two-phase Commit(2PC):保證一個事務跨越多個節點時保持 ACID 特性;算法

兩類節點:協調者(Coordinator)和參與者(Participants),協調者只有一個,參與者能夠有多個。分佈式

過程:spa

  1. 準備階段:協調者詢問參與者事務是否執行成功;3d

  2. 提交階段:若是事務在每一個參與者上都執行成功,協調者發送通知讓參與者提交事務;不然,協調者發送通知讓參與者回滾事務。日誌

須要注意的是,在準備階段,參與者執行了事務,可是還未提交。只有在提交階段接收到協調者發來的通知後,才進行提交或者回滾。blog

存在的問題進程

  • 參與者發生故障。解決方案:能夠給事務設置一個超時時間,若是某個參與者一直不響應,那麼認爲事務執行失敗。事務

  • 協調者發生故障。解決方案:將操做日誌同步到備用協調者,讓備用協調者接替後續工做。ip

 

Paxos(Lamport):

  分佈式系統中的節點通訊存在兩種模型:共享內存(Shared memory)和消息傳遞(Messages passing)。

  基於消息傳遞通訊模型的分佈式系統,不可避免的會發生如下錯誤:進程可能會慢、被殺死或者重啓,消息可能會延遲、丟失、重複,在基礎Paxos場景中,先不考慮可能出現消息篡改即拜占庭錯誤的狀況。

  Paxos算法解決的問題是在一個可能發生上述異常的分佈式系統中如何就某個值達成一致,保證不論發生以上任何異常,都不會破壞決議的一致性

主要有三類節點:

  1. 提議者(Proposer):提議一個值;
  2. 接受者(Acceptor):對每一個提議進行投票;
  3. 告知者(Learner):被告知投票的結果,不參與投票過程。

 

 

過程:

規定一個提議包含兩個字段:[n, v],其中 n 爲序號(具備惟一性),v 爲提議值。

下圖演示了兩個 Proposer 和三個 Acceptor 的系統中運行該算法的初始過程,每一個 Proposer 都會向全部 Acceptor 發送提議請求。

 

 

當 Acceptor 接收到一個提議請求,包含的提議爲 [n1, v1],而且以前還未接收過提議請求,那麼發送一個提議響應,設置當前接收到的提議爲 [n1, v1],而且保證之後不會再接受序號小於 n1 的提議。

以下圖,Acceptor X 在收到 [n=2, v=8] 的提議請求時,因爲以前沒有接收過提議,所以就發送一個 [no previous] 的提議響應,而且設置當前接收到的提議爲 [n=2, v=8],而且保證之後不會再接受序號小於 2 的提議。其它的 Acceptor 相似。

 

若是 Acceptor 接受到一個提議請求,包含的提議爲 [n2, v2],而且以前已經接收過提議 [n1, v1]。若是 n1 > n2,那麼就丟棄該提議請求;不然,發送提議響應,該提議響應包含以前已經接收過的提議 [n1, v1],設置當前接收到的提議爲 [n2, v2],而且保證之後不會再接受序號小於 n2 的提議。

以下圖,Acceptor Z 收到 Proposer A 發來的 [n=2, v=8] 的提議請求,因爲以前已經接收過 [n=4, v=5] 的提議,而且 n > 2,所以就拋棄該提議請求;Acceptor X 收到 Proposer B 發來的 [n=4, v=5] 的提議請求,由於以前接收到的提議爲 [n=2, v=8],而且 2 <= 4,所以就發送 [n=2, v=8] 的提議響應,設置當前接收到的提議爲 [n=4, v=5],而且保證之後不會再接受序號小於 4 的提議。Acceptor Y 相似。

當一個 Proposer 接收到超過一半 Acceptor 的提議響應時,就能夠發送接受請求。

Proposer A 接受到兩個提議響應以後,就發送 [n=2, v=8] 接受請求。該接受請求會被全部 Acceptor 丟棄,由於此時全部 Acceptor 都保證不接受序號小於 4 的提議。

Proposer B 事後也收到了兩個提議響應,所以也開始發送接受請求。須要注意的是,接受請求的 v 須要取它收到的最大 v 值,也就是 8。所以它發送 [n=4, v=8] 的接受請求。

 

 Acceptor 接收到接受請求時,若是序號大於等於該 Acceptor 承諾的最小序號,那麼就發送通知給全部的 Learner。當 Learner 發現有大多數的 Acceptor 接收了某個提議,那麼該提議的提議值就被 Paxos 選擇出來。

 

 

 ---------------------------------------------------------------------------------------------------

Raft(14年):簡化,更容易理解,也更容易實現。

 引入主節點,經過競選。

節點類型:Follower、Candidate 和 Leader

  Leader 會週期性的發送心跳包給 Follower。每一個 Follower 都設置了一個隨機的競選超時時間,通常爲 150ms~300ms,若是在這個時間內沒有收到 Leader 的心跳包,就會變成 Candidate,進入競選階段。

流程:
① 下圖表示一個分佈式系統的最初階段,此時只有 Follower,沒有 Leader。Follower A 等待一個隨機的競選超時時間以後,沒收到 Leader 發來的心跳包,所以進入競選階段。

② 此時 A 發送投票請求給其它全部節點。

③ 其它節點會對請求進行回覆,若是超過一半的節點回復了,那麼該 Candidate 就會變成 Leader。

④ 以後 Leader 會週期性地發送心跳包給 Follower,Follower 接收到心跳包,會從新開始計時。

多個 Candidate 競選

① 若是有多個 Follower 成爲 Candidate,而且所得到票數相同,那麼就須要從新開始投票,例以下圖中 Candidate B 和 Candidate D 都得到兩票,所以須要從新開始投票。

 

② 當從新開始投票時,因爲每一個節點設置的隨機競選超時時間不一樣,所以能下一次再次出現多個 Candidate 並得到一樣票數的機率很低。

日誌複製

① 來自客戶端的修改都會被傳入 Leader。注意該修改還未被提交,只是寫入日誌中。

② Leader 會把修改複製到全部 Follower。

③ Leader 會等待大多數的 Follower 也進行了修改,而後纔將修改提交。

④ 此時 Leader 會通知的全部 Follower 讓它們也提交修改,此時全部節點的值達成一致。

相關文章
相關標籤/搜索