圖解 etcd

KevinYan發表於2019-11-28

用一些圖示結合場景和文字輕鬆瞭解etcd,文章是針對etcd初學者的,目的是讓大家瞭解etcd是什麼、主要在什麼場景下使用、etcd叢集是怎麼工作的以及建立叢集時應該如何選擇叢集的節點數。

etcd 是一個高可用強一致性的鍵值倉庫在很多分散式系統架構中得到了廣泛的應用,其最經典的使用場景就是服務發現。

作為一個受到 ZooKeeper啟發而催生的專案,它除了擁有與之類似的功能外,更專注於以下四點。

  • 簡單:易於部署,易使用。基於 HTTP+JSON 的 API 讓你用 curl 就可以輕鬆使用。
  • 安全:可選 SSL 客戶認證機制。
  • 快速:每個例項每秒支援一千次寫操作。
  • 可信:使用一致性 Raft 演算法充分實現了分散式。

etcd 的場景預設處理的資料都是系統中的控制資料。所以etcd在系統中的角色不是其他NoSQL產品的替代品,更不能作為應用的主要資料儲存。etcd中應該儘量只儲存系統中服務的配置資訊,對於應用資料只推薦把資料量很小,但是更新和訪問頻次都很高的資料儲存在etcd中。

服務發現(Service Discovery)

服務發現要解決的是分散式系統中最常見的問題之一,即在同一個分散式叢集中的程式或服務,要如何才能找到對方並建立連線。本質上來說,服務發現就是想要了解叢集中是否有程式在監聽 udp 或 tcp 埠,並且通過名字就可以查詢和連線。要解決服務發現的問題,需要有下面三大支柱,缺一不可。

  1. 一個強一致性、高可用的服務儲存目錄。基於 Raft 演算法的 etcd 就是一個強一致性高可用的服務儲存目錄。

  2. 一種註冊服務和監控服務健康狀態的機制。使用者可以在 etcd 中註冊服務,並且對註冊的服務設定 key TTL,定時保持服務的心跳以達到監控健康狀態的效果。

  3. 一種查詢和連線服務的機制。通過在 etcd 指定的主題(由服務名稱構成的服務目錄)下注冊的服務也能在對應的主題下查詢到。

etcd的核心元件

img

從 etcd 的架構圖中我們可以看到,etcd 主要分為四個部分。

  • HTTP Server:用於處理使用者傳送的 API 請求以及其它 etcd 節點的同步與心跳資訊請求。
  • Store:用於處理 etcd 支援的各類功能的事務,包括資料索引、節點狀態變更、監控與反饋、事件處理與執行等等,是 etcd 對使用者提供的大多數 API 功能的具體實現。
  • Raft:Raft 強一致性演算法的具體實現,是 etcd 的核心。
  • WAL:Write Ahead Log(預寫式日誌),是 etcd 的資料儲存方式。除了在記憶體中存有所有資料的狀態以及節點的索引以外,etcd 就通過 WAL 進行持久化儲存。WAL 中,所有的資料提交前都會事先記錄日誌。Snapshot 是為了防止資料過多而進行的狀態快照;Entry 表示儲存的具體日誌內容。

通常,一個使用者的請求傳送過來,會經由 HTTP Server 轉發給 Store 進行具體的事務處理,如果涉及到節點的修改,則交給 Raft 模組進行狀態的變更、日誌的記錄,然後再同步給別的 etcd 節點以確認資料提交,最後進行資料的提交,再次同步。

使用者從叢集中哪個節點讀寫資料?

為了保證資料的強一致性,etcd叢集中所有的資料流向都是一個方向,從 Leader (主節點)流向 Follower,也就是所有 Follower 的資料必須與 Leader 保持一致,如果不一致會被覆蓋。

簡單點說就是,使用者可以對etcd叢集中的所有節點進行讀寫,讀取非常簡單因為每個節點儲存的資料是強一致的。對於寫入來說,etcd叢集中的節點會選舉出Leader節點,如果寫入請求來自Leader節點即可直接寫入然後Leader節點會把寫入分發給所有Follower,如果寫入請求來自其他Follower節點那麼寫入請求會給轉發給Leader節點,由Leader節點寫入之後再分發給叢集上的所有其他節點。

下面的圖示中1、3節點都有寫入請求,節點1為Leader所以3的寫入請求會轉發給1,寫入完成後再同步給所有節點。

img

img

img

img

如何選舉Leader節點

假設叢集中有三個節點,叢集啟動之初節點中並沒有被選舉出的Leader。

img

Raft演算法使用隨機Timer來初始化Leader選舉流程。比如說在上面三個節點上都執行了Timer(每個Timer的持續時間是隨機的),第一個節點率先完成了Timer,隨後它就會向其他兩個節點傳送成為Leader的請求,其他節點接收到請求後會以投票迴應然後第一個節點被選舉為Leader。

img

成為Leader後,該節點會以固定時間間隔向其他節點傳送通知,確保自己仍是Leader。有些情況下當Follower們收不到Leader的通知後,比如說Leader節點當機或者失去了連線,其他節點會重複之前選舉過程選舉出新的Leader。

img

判斷寫入是否成功

etcd認為寫入請求被Leader節點處理並分發給了多數節點後,就是一個成功的寫入。如何界定多數節點呢?很簡單,假設總結點數是N,那麼多數節點 Majority=N/2+1,不過在etcd中使用的術語是 Quorum而不是 Majority。所以界定多數節點的公式是 Quorum=N/2+1

關於節點數的最佳實踐

img

關於如何確定etcd叢集應該有多少個節點的問題,上圖的左側的圖表給出了叢集中節點總數(Instances)對應的Quorum數量,用Instances減去Quorom就是叢集中容錯節點(允許出故障的節點)的數量。

所以在叢集中推薦的最少節點數量是3個,因為1和2個節點的容錯節點數都是0,一旦有一個節點宕掉整個叢集就不能正常工作了。

當決定叢集中節點的數量時,強烈推薦奇數數量的節點,比如下圖表中高亮的那幾個選項。

img

具體來說,6個節點的叢集它的容錯能力並沒有比5個節點的好,他們的容錯節點數一樣,一旦容錯節點超過2後,由於Quorum節點數小於4整個叢集也變為不可用的狀態了。

img

所以在決定叢集中的節點數時,奇數要優於偶數。

由於etcd之前接觸的不多網上成體系資料也比較少一開始理解起來有些困難,最近看了不少文章同時偶然在Youtube上發現了一個介紹etcd入門的視訊,覺得很好。文中的圖片大部分都是來自視訊的截圖,推薦能訪問油管的同學都去看看,比看我這裡的文章更易懂。如果英語聽力不太好的同學可以先看看我的文章再去油管上看視訊。

視訊連結 https://www.youtube.com/watch?v=L9xkXzpEY6...

公眾號:網管叨bi叨 | Golang、PHP、Laravel、Docker等學習經驗分享

相關文章