Consual 一致性協議

  Consul使用一致性協議來提供一致性(如CAP定義的)。一致性協議基於「Raft: In search of an Understandable Consensus Algorithm」。Raft的直觀展現,見The Secret Lives of Datahtml

  提示:本頁覆蓋了Consul內部的全部技術細節。有效的操做和使用Consul並不須要這些細節。這些細節是爲了那些不想查閱源代碼但又但願學習的人準備的。算法

Raft協議概述

  Raft是一個基於Paxos的一致性算法。與Paxos相比,Raft被設計得有更少的狀態,更簡單和更好理解。bootstrap

  當討論Raft時,有一些關鍵的術語須要知道:安全

  • Log——Raft系統的基本工做單元是日誌記錄。一致性的問題能夠被分解到複製日誌中。日誌是一個有序的記錄序列。若是全部成員贊成記錄和他們的順序,咱們認爲日誌是一致的。
  • FSM——有限狀態機。有限狀態機是互相轉移的有限的狀態的集合。當有新的日誌,FSM容許在狀態之間轉換。相同日誌序列的應用必須產生相同的狀態,這意味着行爲必須是肯定性的。
  • Peer set——全部參與日誌複製的成員組成了Peer set。對於Consul而言,全部的server節點都在本地數據中心的Peer set中。
  • Quorum(法定人數)——法定人數是Peer set中的大多數成員。對於一個大小爲n的集合,法定人數必須至少是(n/2)+1個成員。例如,若是在Peer set中有5個成員,咱們須要3個節點來組成一個法定人數。若是因爲任何緣由致使法定人數的節點不可用,則集羣是不可用的,而且不會有新的日誌提交。
  • Committed Entry——當一條記錄被持久化的存儲在法定人數的節點中,該記錄被認爲是已提交的。一旦一條記錄被提交他就能夠被應用。
  • Leader——在任何給定時間,Peer set選舉一個節點成爲leader。leader負責處理新提交的記錄,複製到follow上和管理它們。

  Raft是一個複雜的協議,不會在這裏詳細介紹(對於那些但願更全面的瞭解的,完整的規範在這篇文章中)。然而,咱們試圖提供一個更高層次的描述,這有助於創建一個心理模型。服務器

  Raft節點老是處於三個狀態中的一個:follower,candidate和leader。全部的節點最初都是處於follower。在這個狀態節點能夠接受來自leader的日誌和進行投票。若是一段時間沒有收到任何記錄,節點會自我升級爲candidate。在candidate狀態,節點從其它節點處獲取選票,若是candidate獲取法定的選票數,則它晉升爲leader。leader必須接收新的記錄而且複製到其它全部的follower上。另外,若是過期的查詢時不可接受的,全部的查詢也必須在leader上執行。網絡

  一旦一個集羣有一個leader,它能夠接受新的日誌記錄。client能夠請求leader追加新的日誌(從Raft的角度看,日誌是一個不透明的二進制blob)。而後leader將記錄寫入持久化的介質中而且試圖複製到法定人數的follower。一旦日誌記錄被認爲是提交的,它能被應用到有限狀態機上。有限狀態機是應用指定的。在Consul中,咱們使用BoltDB來維護集羣狀態。app

  顯然,容許複製的日誌以無限的方式增加這顯然是不可取的。Raft提供一種快照當前狀態和壓縮日誌的機制。由於FSM是抽象的,重播舊的日誌來恢復FSM的狀態必然致使相同的狀態。這使得Raft能夠在某個時間點計算FSM的狀態,而後刪除全部達到該狀態的日誌。這是自動執行的,無需用戶干預而且防止無限制的使用磁盤,同時也減小了重放日誌的時間。使用BoltDB的一個優勢是,它容許Consul繼續接收新的事務即便舊狀態正在被快照,不會產生任何的問題。ide

  只要有法定人數的節點可用,Consensus是容錯的。若是法定人數的節點不可用,那麼不可能處理日誌或者成員關係。例如,假設這裏有兩個節點:A和B。法定人數也是2,意味着兩個節點都必須贊成提交日誌記錄。若是A或者B失敗了,則不可能達到法定人數。這意味着集羣沒法添加或者刪除或者提交任何日誌記錄。這個結果是不可用的,在這個時候須要手工干預來刪除A或者B,而後以引導模式重啓。性能

  3個節點Raft集羣能夠容忍一個節點的故障,5個節點的集羣能夠容忍兩個節點故障。推薦的配置是每一個數據中心運行3或5個Consul Server。這能夠最大限度的提升可用性,而不會有太大的性能犧牲。下面的部署表總結了潛在的集羣大小和每一個集羣的故障容忍。學習

  在性能方面,Raft比得上Paxos。假設都存在穩定的leader,提交一個日誌記錄須要往返集羣半數節點。所以性能受限於磁盤IO和網絡延遲。儘管Consul不是設計爲高吞吐的寫系統,可是它可否處理每秒成百上千的事務依賴於網絡和硬件配置。

Raft in Consul

   只有Consul server節點加入Raft。全部的Client節點轉發請求到Server。這樣設計的一部分緣由是,隨着更多的節點加入集羣,法定人數的節點也會增長。這會引入性能問題,由於你可能須要等待數百機器而不是少數的來贊成一條記錄。

  當開始時,一個Consul Server被設置成「bootstrap」模式。這個模式容許它選舉本身爲leader。一旦一個leader被選舉,其它機器可以保持一致性和安全性的加入peer set。最終,一旦第一部分機器已經加入,bootstrap模式能夠被禁用。更多細節看這個文檔

  因爲全部的server都加入做爲peer set的一部分,它們都知道當前的leader。當一個RPC請求到達一個非leader的server時,請求被轉發到leader。若是一個RPC是一個查詢類型,意味着它是隻讀,leader生成基於FSM當前狀態的結果。若是RPC是一個事務類型,意味着它修改狀態,leader生成一個新的日誌記錄而且將其用於Raft。一旦一個日誌記錄被提交且應用於FSM,則事務完成。

  因爲Raft的複製性質,性能對網絡延遲是敏感的。因爲這個緣由,每一個數據中心選擇一個獨立的leader並維護一個不相交的peer set。數據按照數據中心分區,因此每一個leader只負責它數據中心的數據。當一個請求被一個遠程數據中心接到,請求被轉發到正確的leader。這種設計在不犧牲一致性的狀況下有較低的事務延遲和更高的可用性。

Consistency Modes

  雖然全部的寫入都經過Raft的日誌複製,讀取更靈活。爲了支持可能須要的各類權衡,Consul支持3中不一樣的讀一致性模式。

  三種模式分別是:

  • default——Raft使用leader租賃過程,該過程提供了一個時間窗口,在該窗口內leader保持穩定的角色。然而,若是一個leader與其餘節點分區,當舊的leader仍然持有租賃時一個新的leader會被選舉出來。這意味着有兩個leader節點。這裏沒有腦裂的風險,由於舊的leader不能提交新日誌。然而,若是舊的leader任然提供任何讀取服務,讀取的值多是舊的。默認的一致性模式只依賴於leader的租賃期,可能暴露給client舊值。作這樣的權衡是由於讀取時快速的,通常是強一致的,而且只有舊值是很難觸發的。讀取舊值的時間窗口也是有界的,由於leader會因爲分區而下臺。
  • consistent——這種模式是強一致的,沒有任何隱憂。它要求leader驗證法定人數的節點,證實它任然是leader。這會引入一個額外的往返全部節點的過程。這種權衡老是一致性的讀取,可是會增長延遲由於有額外的往返時間。
  • stale——這種模式容許在任何服務器上讀取,無論它是否是leader。這意味着可能讀取到任意的陳舊值,可是一般與leader差距50毫秒。這種權衡是快速和可擴展的讀取,可是可能有陳舊值。這種不用leader模式的讀取意味着一個不可用的集羣也可以響應。

Deployment Table

   下表展現了不一樣集羣大小的法定人數和故障容忍。推薦的部署是3或5個server。單臺服務是很是不可取的,由於在故障的狀況下數據丟失是不可避免的。

相關文章
相關標籤/搜索