etcd 非關聯式資料庫 簡介

來源:互聯網
上載者:User

1.什麼是etcd服務

etcd是一個採用HTTP協議的健/值對儲存系統,它是一個分布式和功能層次配置系統,可用於構建服務發現系統。用於共用配置和服務發現的分布式,一致性的KV儲存系統.其很容易部署、安裝和使用,提供了可靠的資料持久化特性。它是安全的並且文檔也十分齊全。

ETCD該項目目前最新穩定版本為3.3.9 具體資訊請參考[項目首頁]和[Github]。ETCD是CoreOS公司發起的一個開源項目,授權協議為Apache.

提供配置共用和服務發現的系統比較多,其中最為大家熟知的是Zookeeper,而ETCD可以算得上是後起之秀了。在項目實現,一致性協議易理解性,營運,安全等多個維度上,ETCD相比Zookeeper都佔據優勢

2.Zookeeper和etcd的區別:

1)一致性協議: ETCD使用Raft協議, .Zookeeper使用ZAB(類PAXOS協議),前者容易理解,方便工程實現;

2)營運方面:ETCD方便營運,ZK難以營運;

3)項目活躍度:ETCD社區與開發活躍,ZK已經快死了;

4)API:ETCD提供HTTP+JSON, gRPC介面,跨平台跨語言,ZK需要使用其用戶端;

5)訪問安全方面:ETCD支援HTTPS訪問,ZK在這方面缺失;

3.etcd的應用情境:

組態管理,服務註冊於發現,選主,應用調度,分布式隊列,分布式鎖

4.Etcd 主要提供以下能力:

1)提供儲存以及擷取資料的介面,它通過協議保證 Etcd 叢集中的多個節點資料的強一致性。用於儲存元資訊以及共用配置。

2)提供監聽機制,用戶端可以監聽某個key或者某些key的變更(v2和v3的機制不同,參看後面文章)。用於監聽和推送變更。

3)提供key的到期以及續約機制,用戶端通過定時重新整理來實現續約(v2和v3的實現機制也不一樣)。用於叢集監控以及服務註冊發現。

4)提供原子的CAS(Compare-and-Swap)和 CAD(Compare-and-Delete)支援(v2通過介面參數實現,v3通過批量事務實現)。用於分布式鎖以及leader選舉。

5.etcd的工作原理:

ETCD使用Raft協議來維護叢集內各個節點狀態的一致性。簡單說,ETCD叢集是一個分布式系統,由多個節點相互連信構成整體對外服務,每個節點都儲存了完整的資料,並且通過Raft協議保證每個節點維護的資料是一致的。

工作原理圖

,每個ETCD節點都維護了一個狀態機器,並且,任意時刻至多存在一個有效主節點。主節點處理所有來自用戶端寫操作,通過Raft協議保證寫操作對狀態機器的改動會可靠的同步到其他節點。

6. 叢集節點數量

ETCD使用RAFT協議保證各個節點之間的狀態一致。根據RAFT演算法原理,節點數目越多,會降低叢集的寫效能。這是因為每一次寫操作,需要叢集中大多數節點將日誌落盤成功後,Leader節點才能將修改內部狀態機器,並返回將結果返回給用戶端。

也就是說在等同配置下,節點數越少,叢集效能越好。顯然,只部署1個節點是沒什麼意義的。通常,按照需求將叢集節點部署為3,5,7,9個節點。

這裡能選擇偶數個節點嗎? 最好不要這樣。原因有二:

1)偶數個節點叢集不可用風險更高,表現在選主過程中,有較大機率或等額選票,從而觸發下一輪選舉。

2)偶數個節點叢集在某些網路分割的情境下無法正常工作。試想,當網路分割發生後,將叢集節點對半分割開。此時叢集將無法工作。按照RAFT協議,此時叢集寫操作無法使得大多數節點同意,從而導致寫失敗,叢集無法正常工作。

7.節點遷移

在生產環境中,不可避免遇到機器硬體故障。當遇到硬體故障發生的時候,我們需要快速恢複節點。ETCD叢集可以做到在不遺失資料的,並且不改變節點ID的情況下,遷移節點。

具體辦法是:

1)停止待遷移節點上的etc進程;

2)將資料目錄打包複製到新的節點;

3)更新該節點對應叢集中peer url,讓其指向新的節點;

4)使用相同的配置,在新的節點上啟動etcd進程;

8.Etcd v2 與 v3區別

Etcd v2 和 v3 本質上是共用同一套 raft 協議代碼的兩個獨立的應用,介面不一樣,儲存不一樣,資料互相隔離。也就是說如果從 Etcd v2 升級到 Etcd v3,原來v2 的資料還是只能用 v2 的介面訪問,v3 的介面建立的資料也只能訪問通過 v3 的介面訪問。所以我們按照 v2 和 v3 分別分析:

1)Etcd v2 儲存,Watch以及到期機制

Etcd v2 儲存結構圖

Etcd v2 是個純記憶體的實現,並未即時將資料寫入到磁碟,持久化機制很簡單,就是將store整合序列化成json寫入檔案。資料在記憶體中是一個簡單的樹結構

當用戶端調用watch介面(參數中增加 wait參數)時,如果請求參數中有waitIndex,並且waitIndex 小於 currentIndex,則從 EventHistroy 表中查詢index小於等於waitIndex,並且和watch key 匹配的 event,如果有資料,則直接返回。如果曆史表中沒有或者請求沒有帶 waitIndex,則放入WatchHub中,每個key會關聯一個watcher列表。 當有變更操作時,變更產生的event會放入EventHistroy表中,同時通知和該key相關的watcher。

這裡有幾個影響使用的細節問題:

1)EventHistroy 是有長度限制的,最長1000。也就是說,如果你的用戶端停了許久,然後重新watch的時候,可能和該waitIndex相關的event已經被淘汰了,這種情況下會丟失變更。

2)如果通知watch的時候,出現了阻塞(每個watch的channel有100個緩衝空間),Etcd 會直接把watcher刪除,也就是會導致wait請求的串連中斷,用戶端需要重新串連。

3)Etcd store的每個node中都儲存了到期時間,通過定時機制進行清理。

從而可以看出,Etcd v2 的一些限制:

1)到期時間只能設定到每個key上,如果多個key要保證生命週期一致則比較困難。

2)watch只能watch某一個key以及其子節點(通過參數 recursive),不能進行多個watch。

3)很難通過watch機制來實現完整的資料同步(有丟失變更的風險),所以當前的大多數使用方式是通過watch得知變更,然後通過get重新擷取資料,並不完全依賴於watch的變更event。


2)Etcd v3 儲存,Watch以及到期機制

Etcd v3 儲存結構圖

Etcd v3 將watch和store拆開實現,我們先分析下store的實現。

Etcd v3 store 分為兩部分,一部分是記憶體中的索引,kvindex,是基於google開源的一個golang的btree實現的,另外一部分是後端儲存。按照它的設計,backend可以對接多種儲存,當前使用的boltdb。boltdb是一個單機的支援事務的kv儲存,Etcd 的事務是基於boltdb的事務實現的。Etcd 在boltdb中儲存的key是reversion,value是 Etcd 自己的key-value組合,也就是說 Etcd 會在boltdb中把每個版本都儲存下,從而實現了多版本機制。

reversion主要由兩部分組成,第一部分main rev,每次事務進行加一,第二部分sub rev,同一個事務中的每次操作加一。第一次操作的main rev是3,第二次是4。當然這種機制大家想到的第一個問題就是空間問題,所以 Etcd 提供了命令和設定選項來控制compact,同時支援put操作的參數來精確控制某個key的曆史版本數。

瞭解了 Etcd 的磁碟儲存,可以看出如果要從boltdb中查詢資料,必須通過reversion,但用戶端都是通過key來查詢value,所以 Etcd 的記憶體kvindex儲存的就是key和reversion之前的映射關係,用來加速查詢。

然後我們再分析下watch機制的實現。Etcd v3 的watch機制支援watch某個固定的key,也支援watch一個範圍(可以用於類比目錄的結構的watch),所以 watchGroup 包含兩種watcher,一種是 key watchers,資料結構是每個key對應一組watcher,另外一種是 range watchers, 資料結構是一個 IntervalTree(不熟悉的參看文文末連結),方便通過區間尋找到對應的watcher。

同時,每個 WatchableStore 包含兩種 watcherGroup,一種是synced,一種是unsynced,前者表示該group的watcher資料都已經同步完畢,在等待新的變更,後者表示該group的watcher資料同步落後於當前最新變更,還在追趕。

當 Etcd 收到用戶端的watch請求,如果請求攜帶了revision參數,則比較請求的revision和store當前的revision,如果大於當前revision,則放入synced組中,否則放入unsynced組。同時 Etcd 會啟動一個背景goroutine持續同步unsynced的watcher,然後將其遷移到synced組。也就是這種機制下,Etcd v3 支援從任意版本開始watch,沒有v2的1000條曆史event表限制的問題(當然這是指沒有compact的情況下)。

另外我們前面提到的,Etcd v2在通知用戶端時,如果網路不好或者用戶端讀取比較慢,發生了阻塞,則會直接關閉當前串連,用戶端需要重新發起請求。Etcd v3為瞭解決這個問題,專門維護了一個推送時阻塞的watcher隊列,在另外的goroutine裡進行重試。

Etcd v3 對到期機制也做了改進,到期時間設定在lease上,然後key和lease關聯。這樣可以實現多個key關聯同一個lease id,方便設定統一的到期時間,以及實現批量續約。


9.相比Etcd v2, Etcd v3的一些主要變化:

1)介面通過grpc提供rpc介面,放棄了v2的http介面。優勢是長串連效率提升明顯,缺點是使用不如以前方便,尤其對不方便維護長串連的情境。

2)廢棄了原來的目錄結構,變成了純粹的kv,使用者可以通過首碼匹配模式類比目錄。

3)記憶體中不再儲存value,同樣的記憶體可以支援儲存更多的key。

4)watch機制更穩定,基本上可以通過watch機制實現資料的完全同步。

5)(提供了大量操作以及事務機制,使用者可以通過批量事務請求來實現Etcd v2的CAS機制(批量事務支援if條件判斷)


10.Etcd 使用注意事項

1)Etcd cluster 初始化的問題

如果叢集第一次初始化啟動的時候,有一台節點未啟動,通過v3的介面訪問的時候,會報告Error:  Etcdserver: not capable 錯誤。這是為相容性考慮,叢集啟動時預設的API版本是2.3,只有當叢集中的所有節點都加入了,確認所有節點都支援v3介面時,才提升叢集版本到v3。這個只有第一次初始化叢集的時候會遇到,如果叢集已經初始化完畢,再掛掉節點,或者叢集關閉重啟(關閉重啟的時候會從持久化資料中載入叢集API版本),都不會有影響。

2)Etcd 讀請求的機制

v2  quorum=true 的時候,讀取是通過raft進行的,通過cli請求,該參數預設為true。

v3  –consistency=“l” 的時候(預設)通過raft讀取,否則讀取本機資料。sdk 代碼裡則是通過是否開啟:WithSerializable option 來控制。

一致性讀取的情況下,每次讀取也需要走一次raft協議,能保證一致性,但效能有損失,如果出現網路磁碟分割,叢集的少數節點是不能提供一致性讀取的。但如果不設定該參數,則是直接從本地的store裡讀取,這樣就損失了一致性。使用的時候需要注意根據應用情境設定這個參數,在一致性和可用性之間進行取捨。

3)Etcd 的 compact 機制

Etcd 預設不會自動 compact,需要設定啟動參數,或者通過命令進行compact,如果變更頻繁建議設定,否則會導致空間和記憶體的浪費以及錯誤。Etcd v3 的預設的 backend quota 2GB,如果不 compact,boltdb 檔案大小超過這個限制後,就會報錯:”Error: etcdserver: mvcc: database space exceeded”,導致資料無法寫入。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.