分佈式共識(Raft)問題研究

背景

隨着雲計算的發展,分佈式系統已是幾乎全部中大型系統的架構選擇。在分佈式系統中,原先單機系統中簡單的問題變得複雜。如鎖的實現由單進程多線程內部的鎖變爲分佈式鎖,分佈式數據庫中如何保證集羣數據一致性,或者更準確的說,集羣如何達成共識git

對於分佈式系統,必須有一個指揮官對系統進行集中控制,指揮系統各部件協同工做,否則你們各幹各的,最終確定是亂套了。而這個指揮官若是是單機部署的,又會出現單點問題,因此指揮官也必須集羣部署,並且要從集羣中選出一個大將軍做爲系統的指揮官,當這個大將軍掛掉的時候,系統能選擇新的大將軍接管系統。github

本文要探討的分佈式共識問題,主要是探討大將軍如何選擇,以及它如何指揮系統協同工做。這個大將軍,在分佈式系統中,稱做分佈式應用程序協調服務,業界比較流行的有Zookeeper和ETCD等。算法

拜占庭將軍問題

說到分佈式一致性問題,不得不提的是拜占庭將軍問題。拜占庭將軍問題(Byzantine failures),是由萊斯利·蘭伯特提出的點對點通訊中的基本問題。含義是在存在消息丟失的不可靠信道上試圖經過消息傳遞的方式達到一致性是不可能的。
因爲拜占庭問題須要考慮在有叛徒和敵方間諜的狀況,問題比較複雜,根據信息系統通訊的現狀,主要是主機掛掉或網絡中斷的狀況,而不考慮惡意僞造消息,所以對一致性的研究通常假設信道是可靠的,或不存在本問題。數據庫

推選大將軍

分佈式系統的第一步,是要選出大將軍做爲系統指揮官,基於簡化的拜占庭將軍模型(即沒有叛徒和間諜,但通訊兵可能被暗殺),首先咱們先來看下將軍們如何選舉出大將軍網絡

假設有A、B、C三個指揮官,他們知足如下條件:多線程

  1. 指揮官個數大於等於3,且爲奇數個。
  2. 每一個指揮官都有一個隨機計時器選舉計時器 election timeout ,時間一到,這位將軍就發起一輪推舉大將軍的活動,自薦爲大將軍候選人,並派出通信兵,詢問其餘指揮官是否贊成推舉本身爲大將軍,同時重置選舉計時器等待你們的回覆。
  3. 其餘指揮官收到推舉大將軍的信息後,若是他沒有推舉過大將軍,就贊成此請,由通信兵回覆,並重置本身的選舉計時器
  4. 每一個指揮官每輪只能贊成一次。
  5. 若是候選人收到大多數(超過半數)指揮官贊成,則此指揮官成爲大將軍。
  6. 成爲大將軍後,大將軍經過心跳計時器 heatbeat timeout 向個指揮官下達做戰命令。
  7. 若是某位指揮官的選舉計時器結束時,推舉尚未成功,則本輪推舉失敗,取消全部指揮官候選人資格,重複執行上述第一步,直到推舉成功爲止。
  8. 選舉成功後,每位指揮官維護一個心跳計時器,若是計時結束時,尚未收到大將軍的命令,則認爲大將軍陣亡,從新啓動推舉活動。

這就是Raft共識算法選主 Leader Election 的過程。從拜占庭將軍的故事映射到分佈式系統上,每一個將軍至關於一個分佈式網絡節點,每一個節點有三種狀態:Follower(指揮官),Candidate(候選人),Leader(大將軍),狀態之間是互相轉換的。架構

注:分佈式

  1. 選舉計數器的時長設置,每一個指揮官不同,通常爲150ms-300ms,這樣能夠避免你們的計時器一塊兒結束。

大將軍發佈命令

大將軍發佈命令後,須要等大多數(超過一半)的指揮官回覆收到命令,命令纔算發佈成功。對應到Raft共識算法,這就是複製日誌 Log Replication雲計算

  1. 大將軍發佈命令,這是命令爲未確認 Uncommitted 狀態。
  2. 通訊兵把命令發送各指揮官。
  3. 指揮官收到命令後,保存命令,狀態也是未確認,並回復。
  4. 當大將軍收到多數指揮官回覆時,任務命令發送成功,把命令狀態修改成已確認 Committed
  5. 大將軍再次向各指揮官發送確認消息。
  6. 各指揮官把消息狀態改完已確認

以上主要以通俗的方式描述了下Raft共識算法的大體流程,詳細的流程及異常處理,網絡有不少的文章,這裏再也不重複。線程

參考資料:
共識算法:Raft
Understandable Distributed Consensus
The Raft Consensus Algorithm

相關文章
相關標籤/搜索