深入理解 etcd:基於原理解析

本文將主要分享以下三方面的內容:

  1. 第一部分,會為大家介紹 etcd 項目發展的整個歷程,從誕生至今 etcd 經歷的那些重要的時刻;
  2. 第二部分,會為大家介紹 etcd 的技術架構以及其內部的實現機制,通過對技術架構和內部機制的學習,幫助我們正確地使用 etcd;
  3. 第三部分,結合具體的使用場景,為大家介紹在分佈式系統中 etcd 所扮演的角色。

etcd 項目的發展歷程#

etcd 誕生於 CoreOS 公司,它最初是用於解決集群管理系統中 OS 升級的分佈式併發控制以及配置文件的存儲與分發等問題。基於此,etcd 被設計為提供高可用、強一致的小型 keyvalue 數據存儲服務。

項目當前隸屬於 CNCF 基金會,被 AWS、Google、Microsoft、Alibaba 等大型互聯網公司廣泛的使用。

深入理解 etcd:基於原理解析

最初,在 2013 年 6 月份由 CoreOS 公司向 GitHub 中提交了第一個版本的初始代碼。

到了 2014 年的 6 月,社區發生了一件事情,Kubernetes v0.4 版本發佈。這裡有必要介紹一下 Kubernetes 項目,它首先是一個容器管理平臺,由谷歌開發並貢獻給社區,因為它集齊了谷歌在容器調度以及集群管理等領域的多年經驗,從誕生之初就備受矚目。在 Kubernetes v0.4 版本中,它使用了 etcd 0.2 版本作為實驗核心元數據的存儲服務,自此 etcd 社區得到了飛速的發展。

很快,在 2015 年 2 月份,etcd 發佈了第一個正式的穩定版本 2.0。在 2.0 版本中,etcd 重新實踐了 Raft 一致性算法,另外用戶提供了一個簡單的樹形數據視圖,在 2.0 版本中 etcd 支持每秒超過 1000 次的寫入性能,滿足了當時絕大多數的應用場景需求。2.0 版本發佈之後,經過不斷的迭代與改進,其原有的數據存儲方案逐漸成為了新世紀的性能瓶頸,因此 etcd 啟動了 v3 版本的方案設計。

2017 年 1 月份的時候,etcd 發佈了 3.1 版本,基本上標誌著 v3 版本方案的全面成熟。在 v3 版本中 etcd 提供了一套全新的 API,並且重新實踐了更有效的一致性讀取方法,同時提供了一個 gRPC 接口。gRPC 的 proxy 用於擴展 etcd 的讀取性能,同時在 v3 版本的方案中包含了大量的 GC 的優化,極大地提高了 etcd 的性能。在該版本中 etcd 可以支持每秒超過 10000 次的寫入。

2018 年,CNCF 基金會下的眾多項目都使用了 etcd 作為其核心的數據存儲。據不完全統計,使用 etcd 的項目超過了 30 個,在同年 11 月份,etcd 項目自身也成為了 CNCF 旗下的孵化項目。進入 CNCF 基金會後,etcd 擁有了超過 400 個貢獻組,其中包含了來自 AWS、Google、Alibaba 等 8 個公司的 9 個項目維護者。

2019 年,etcd 即將發佈全新的 3.4 版本,該版本由 Google、Alibaba 等公司聯合打造,將進一步改進 etcd 的性能及穩定性,以滿足在超大型公司使用中苛刻的場景要求。

架構及內部機制解析#

內部機制解析#

etcd 是一個分佈式的、可靠的 key-value 存儲系統,它用於存儲分佈式系統中的關鍵數據,這個定義非常重要。

深入理解 etcd:基於原理解析

一個 etcd 集群,通常會由 3 個或者 5 個節點組成,多個節點之間,通過一個叫做 Raft 一致性算法的方式完成分佈式一致性協同,算法會選舉出一個主節點作為 leader,由 leader 負責數據的同步與數據的分發,當 leader 出現故障後,系統會自動地選取另一個節點成為 leader,並重新完成數據的同步與分發。客戶端在眾多的 leader 中,僅需要選擇其中的一個就可以完成數據的讀寫。

在 etcd 整個的架構中,有一個非常關鍵的概念叫做 quorum,quorum 的定義是 =(n+1)/2,也就是說超過集群中半數節點組成的一個團體,在 3 個節點的集群中,etcd 可以容許 1 個節點故障,也就是隻要有任何 2 個節點重合,etcd 就可以繼續提供服務。同理,在 5 個節點的集群中,只要有任何 3 個節點重合,etcd 就可以繼續提供服務。這也是 etcd 集群高可用的關鍵。

當我們在允許部分節點故障之後,繼續提供服務,這裡就需要解決一個非常複雜的問題,即分佈式一致性。在 etcd 中,該分佈式一致性算法由 Raft 一致性算法完成,這個算法本身是比較複雜的,我們這裡就不展開詳細介紹了。

但是這裡面有一個關鍵點,它基於一個前提:任意兩個 quorum 的成員之間一定會有一個交集,也就是說只要有任意一個 quorum 存活,其中一定存在某一個節點,它包含著集群中最新的數據。正是基於這個假設,這個一致性算法就可以在一個 quorum 之間採用這份最新的數據去完成數據的同步,從而保證整個集群向前衍進的過程中其數據保持一致。

深入理解 etcd:基於原理解析

雖然 etcd 內部的機制比較複雜,但是 etcd 給客戶提供的接口是比較簡單的。如上圖所示,我們可以通過 etcd 提供的客戶端去訪問集群的數據,也可以直接通過 http 的方式,類似像 curl 命令直接訪問 etcd。在 etcd 內部,其數據表示也是比較簡單的,我們可以直接把 etcd 的數據存儲理解為一個有序的 map,它存儲著 key-value 數據。同時 etcd 為了方便客戶端去訂閱資料的數據,也支持了一個 watch 機制,我們可以通過 watch 實時地拿到 etcd 中數據的增量更新,從而保持與 etcd 中的數據同步。

etcd API 接口#

接下來我們看一下 etcd 提供的接口,這裡將 etcd 的接口分為了 5 組:

深入理解 etcd:基於原理解析

  • 第一組是 Put 與 Delete。上圖可以看到 put 與 delete 的操作都非常簡單,只需要提供一個 key 和一個 value,就可以向集群中寫入數據了,那麼在刪除數據的時候,只需要提供 key 就可以了;
  • 第二組操作是查詢操作。查詢操作 etcd 支持兩種類型的查詢:第一種是指定單個 key 的查詢,第二種是指定的一個 key 的範圍;
  • 第三組操作:etcd 啟動了 Watch 的機制,也就是我們前面提到的用於實現增量的數據更新,watch 也是有兩種使用方法,第一種是指定單個 key 的 Watch,另一種是指定一個 key 的前綴。在實際應用場景的使用過程中,經常採用第二種;
  • 第四組:API 是 etcd 提供的一個事務操作,可以通過指定某些條件,當條件成立的時候執行一組操作。當條件不成立的時候執行另外一組操作;
  • 第五組是 Leases 接口。Leases 接口是分佈式系統中常用的一種設計模式,後面會具體介紹。

etcd 的數據版本號機制#

要正確使用 etcd 的 API,必須要知道內部對應數據版本號的基本原理。

  • 首先 etcd 中有個 term 的概念,代表的是整個集群 Leader 的標誌。當集群發生 Leader 切換,比如說 Leader 節點故障,或者說 Leader 節點網絡出現問題,再或者是將整個集群停止後再次拉起,這個時候都會發生 Leader 的切換。當 Leader 切換的時候,term 的值就會 +1。
  • 第二個版本號叫做 revision,revision 代表的是全局數據的版本。當數據發生變更,包括創建、修改、刪除,revision 對應的都會 +1。在任期內,revision 都可以保持全局單調遞增的更改。正是 revision 的存在才使得 etcd 既可以支持數據的 MVCC,也可以支持數據的 Watch。
  • 對於每一個 KeyValue 數據,etcd 中都記錄了三個版本:
  • 第一個版本叫做 create_revision,是 KeyValue 在創建的時候生成的版本號;
  • 第二個叫做 mod_revision,是其數據被操作的時候對應的版本號;
  • 第三個 version 就是一個計數器,代表了 KeyValue 被修改了多少次。

這裡可以用圖的方式給大家展示一下:

深入理解 etcd:基於原理解析

在同一個 Leader 任期之內,我們發現所有的修改操作,其對應的 term 值都等於 2,始終保持不變,而 revision 則保持單調遞增。

當重啟集群之後,我們會發現所有的修改操作對應的 term 值都變成了 3。在新的任期內,所有的 term 值都等於3,且不會發生變化。而對應的 revision 值同樣保持單調遞增。

從一個更大的維度去看,可以發現:在多個任期內,其數據對應的 revision 值會保持全局的單調遞增。

etcd mvcc & streaming watch#

瞭解 etcd 的版本號控制後,接下來介紹一下 etcd 多版本號的併發控制以及 watch 的使用方法。

首先,在 etcd 中,支持對同一個 Key 發起多次數據修改。因為已經知道每次數據修改都對應一個版本號,多次修改就意味著一個 key 中存在多個版本,在查詢數據的時候可以通過不指定版本號查詢,這時 etcd 會返回該數據的最新版本。當我們指定一個版本號查詢數據後,可以獲取到一個 Key 的歷史版本。

深入理解 etcd:基於原理解析

為每次操作修改數據的時候都會對應一個版本號。 在 watch 的時候指定數據的版本,創建一個 watcher,並通過這個 watcher 提供的一個數據管道,能夠獲取到指定的 revision 之後所有的數據變更。如果指定的 revision 是一箇舊版本,可以立即拿到從舊版本到當前版本所有的數據更新。並且,watch 的機制會保證 etcd 中,該 Key 的數據發生後續的修改後,依然可以從這個數據管道中拿到數據增量的更新。

為了更好地理解 etcd 的多版本控制以及 watch 的機制,可以簡單的介紹一下 etcd 的內部實現。

深入理解 etcd:基於原理解析

在 etcd 中所有的數據都存儲在一個 b+tree 中。b+tree 是保存在磁盤中,並通過 mmap 的方式映射到內存用來查詢操作。

在 b+tree 中(如圖所示灰色部分),維護著 revision 到 value 的映射關係。也就是說當指定 revision 查詢數據的時候,就可以通過該 b+tree 直接返回數據。當我們通過 watch 來訂閱數據的時候,也可以通過這個 b+tree 維護的 revision 到 value 映射關係,從而通過指定的 revision 開始遍歷這個 b+tree,拿到所有的數據更新。

同時在 etcd 內部還維護著另外一個 b+tree。它管理著 key 到 revision 的映射關係。當需要查詢 Key 對應數據的時候,會通過藍色方框的 b+tree,將 key 翻譯成 revision。再通過灰色框 b+tree 中的 revision 獲取到對應的 value。至此就能滿足客戶端不同的查詢場景了。

這裡需要提兩點:

  • 一個數據是有多個版本的;
  • 在 etcd 持續運行過程中會不斷的發生修改,意味著 etcd 中內存及磁盤的數據都會持續增長。這對資源有限的場景來說是無法接受的。因此在 etcd 中會週期性的運行一個 Compaction 的機制來清理歷史數據。對於一個 Key 的歷史版本數據,可以選擇清理掉。

etcd mini-transactions#

在理解了 mvcc 機制及 watch 機制之後,來介紹一下 etcd 提供的 mini-transactions 機制。etcd 的 transaction 機制比較簡單,基本可以理解為一段 if-else 程序,在 if 中可以提供多個操作。

深入理解 etcd:基於原理解析

在上圖的示例中,if 裡面寫了兩個條件。當 Value(key1) 大於“bar”,並且 Version(key1) 的版本等於 2 的時候,執行 Then 裡面指定的操作:修改 Key2 的數據為 valueX,同時刪除 Key3 的數據。如果不滿足條件,則執行另外一個操作:Key2 修改為 valueY。

在 etcd 內部會保證整個事務操作的原子性。也就是說 If 操作所有的比較條件,其看到的視圖,一定是一致的。同時它能夠確保在爭執條件中,多個操作的原子性不會出現 etc 僅執行了一半的情況。

通過 etcd 提供的事務操作,我們可以在多個競爭中去保證數據讀寫的一致性,比如說前面已經提到過的 Kubernetes 項目,它正是利用了 etcd 的事務機制,來實現多個 KubernetesAPI server 對同樣一個數據修改的一致性。

etcd lease 的概念及用法#

lease 是分佈式系統中一個常見的概念,用於代表一個租約。通常情況下,在分佈式系統中需要去檢測一個節點是否存活的時候,就需要租約機制。

深入理解 etcd:基於原理解析

上圖示例中首先創建了一個 10s 的租約,如果創建租約後不做任何的操作,那麼 10s 之後,這個租約就會自動過期。

在這裡,接著將 key1 和 key2 兩個 key value 綁定到這個租約之上,這樣當租約過期時,etcd 就會自動清理掉 key1 和 key2 對應的數據。

如果希望這個租約永不過期,比如說需要檢測分佈式系統中一個進程是否存活,那麼就會在這個分佈式進程中去訪問 etcd 並且創建一個租約,同時在該進程中去調用 KeepAlive 的方法,與 etcd 保持一個租約不斷的續約。試想一下,如果這個進程掛掉了,這時就沒有辦法再繼續去開發 Alive。租約在進程掛掉的一段時間就會被 etcd 自動清理掉。所以可以通過這個機制來判定節點是否存活。

在 etcd 中,允許將多個 key 關聯在統一的 lease 之上,這個設計是非常巧妙的,事實上最初的設計也不是這個樣子。通過這種方法,將多個 key 綁定在同一個lease對象,可以大幅地減少 lease 對象刷新的時間。試想一下,如果大量的 key 都需要綁定在同一個 lease 對象之上,每一個 key 都去更新這個租約的話,這個 etcd 會產生非常大的壓力。通過支持加多個 key 綁定在同一個 lease 之上,它既不失靈活性同時能夠大幅改進 etcd 整個系統的性能。

實例演示#

etcd 基本的讀寫操作

這裡為大家以實際 demo 的方式來演示一些 etcd 的基本的操作。首先啟動一個 etcd,會發現 etcd 已經成功啟動了。

深入理解 etcd:基於原理解析

啟動 etcd 之後,就可以通過 etcd 客戶端來操作 etcd 的數據了。比如說向 etcd 中插入一條數據,在插入一條數據後,可以通過 get 方法來查詢到這條數據。如下圖所示:

深入理解 etcd:基於原理解析

為了展示 etcd 查詢的基本內容,這裡直接創建 10 個 key value,分別為 key0~key9,所以我們就向 etcd 中插入了 10 條數據。

深入理解 etcd:基於原理解析

可以查詢其中的 key5,同時也支持查詢 key 的範圍。指定一個 key 的起始的範圍,以及 key 的結束範圍。注意:結束範圍是不包含的,也就是說當查詢 key2~key6 的時候,etcd 會返回 key2、key3、key4、key5 四條數據。

深入理解 etcd:基於原理解析

etcd 還支持指定前綴的查詢。通過這種方式,可以發現 etcd 會返回 key0~key9 所有的數據。

深入理解 etcd:基於原理解析

前面提到的 etcd 中的版本,對於 key0 來說,可以通過 -w 指定 json 的方式來輸出。下面格式化一個 json 字符串,發現該操作對應返回了其中的第一條數據,並且在返回體中包含了一個消息頭。該消息頭描述了 etcd 全局的信息,其中的 class ID 和 member ID 暫時先忽略掉。那麼這裡的 raft_term 就是我們在前面提到的 etcd 的全局版本號 term,當前 term 值是 2,發現所有的操作中 term 值對應的都是 2。

深入理解 etcd:基於原理解析

假如換成 key5,如下圖所示,發現對應的 term 值依然是 2。同時集群全局的版本號 revision 當前是 12,因為我們沒有發起任何的數據修改。

深入理解 etcd:基於原理解析

這時可以嘗試再插入一條數據。當再次查詢 etcd key5 的數據時,會發現全局的 revision 已經變成了 13,因為剛才又新增了一條數據,同時當前的 term 值依然是保持不變的。

在返回的數據中,所有包含的 key value 以外,它還包含著 etcd 提供的三個 revision。這裡我們會發現,key5 對應創建的 revision 是 8,同時它修改的 revision 也是 8,因為我們沒有對 key5 發起過任何的修改,與此同時,它對應的 version 是 1。

深入理解 etcd:基於原理解析

當對 key5 發起修改的時候,下圖中可以看到,其對應的 mod_revision 已經變成了 14,修改的 revision 並不是 +1 的關係,而是採用當前操作對應的 revision。同樣,因為已經發生了一次修改,那麼 key5 的版本號就會從 1 變成 2。

深入理解 etcd:基於原理解析

那麼如果再一次修改 key5 的數據,保持數據不變,還是 x,會發生什麼情況呢?

如下圖所示,集群全局的 revision 變成了 15,key5 的 mod_revision 也變成了 15,key5 的 version 變成了 3。可以發現:對同一個 key 寫入同一個 value,其版本號依然會變化。

深入理解 etcd:基於原理解析

如果刪除這個數據,重新產生 key5 這個數據,從下圖可以發現,當前的 revision 又增加了一次。因為刪除也是一次修改操作,但數據已經沒有了。

深入理解 etcd:基於原理解析

如果重新插入 key5,這時全局的 revision 變成了 17、key5 的 create_revision 是 17、對應修改的 revision 也是 17;但 value 值卻變成了 1,又重新開始計數,這是因為 value 代表著 key 被修改的次數。

深入理解 etcd:基於原理解析

在同一個任期內的 term 值是不發生變化的。如果嘗試停掉 etcd,並且重新啟動 etcd。當再次查詢 key5 的數據時,將會發現集群已經從 2 變成了 3,但全局的數據的 revision 是不變的。

深入理解 etcd:基於原理解析

如果這時再次修改 key5,會發現跟剛才的規律一樣:集群全局的 revision +1、key5 創建的 revision 保持不變。但是修改的 revision 為本次操作的版本,同時,其 value 修改過一次之後 version 變成了2。

這裡需要注意到:key 和 value 在 etcd 中的表示並不是字符串的形式,而是二進制的形式,這裡輸出的時候是以 base64 編碼的。

深入理解 etcd:基於原理解析

如果需要知道 etcd 的數據內容,那麼可以通過 get key5,或者可以通過反解 base 64 的方式來實現。如下圖執行命令後得到的值為 valueX。

深入理解 etcd:基於原理解析

etcd 的 watch操作

接下來看一下 etcd 提供的 watch 操作,來 watch key5 的變化。再開一個窗口去寫入 key5 的數據,當數據被寫入的時候,原本的 watch 就能及時拿到數據的更新,它可以非常實時地感覺到數據的變化。同時嘗試寫入 key4 的數據,則 watch 是不會收到數據更新的。

深入理解 etcd:基於原理解析

前面我們提到了 etcd 是支持指定前綴 watch的。如果指定前綴 key,那麼在寫入 key4 的時候,我們能收到更新;寫入 key5 的時候,依然能收到更新。通過這種方式,我們就可以實現 etcd 的數據同步了。

深入理解 etcd:基於原理解析

這裡可以給大家留一個課後作業,可以嘗試使用 etcd 的客戶端,來實現一個同步 etcd 指定前綴的數據版本的功能。

etcd 事務操作

etcd 客戶端還提供了一些事務操作的語義。比如說 key5 的數據等於一個不成立的條件,隨便寫一個“whatever”,那麼顯然成功操作的時候將會失敗;成功操作寫一個讀取操作,失敗的時候嘗試將 key5 重新寫為 value5,同時將 key4 寫為 valueX。當事務成功以後,重新去查 key5 的數據,就會發現 key5 已經被寫成 value5 了,key4 也被更新為對應的 valueX。

深入理解 etcd:基於原理解析

demo 的演示到這裡就結束了。

三、典型的使用場景介紹#

元數據存儲-Kubernetes#

因為 Kubernetes 將自身所用的狀態設備存儲在 etcd 中,其狀態數據的存儲的複雜性將 etcd 給 cover 掉之後,Kubernetes 系統自身不需要再樹立複雜的狀態流轉,因此自身的系統設立架構也得到了大幅的簡化。

深入理解 etcd:基於原理解析

Server Discovery (Naming Service)#

第二個場景是 Service Discovery,也叫做名字服務。在分佈式系統中,通常會出現的一個模式就是需要後端多個,可能是成百上千個進程來提供一組對等的服務,比如說檢索服務、推薦服務。

深入理解 etcd:基於原理解析

對於這樣一種後端服務,通常情況下為了簡化後端服務的運維成本,後端的這一進程會被類似 Kubernetes 這樣的集群管理系統所調度,也就是說,我們事先無法知道這一組進程分佈在哪裡。為了解決這個問題,可以利用 etcd來解決資源註冊的問題,當這一組後端進程被調度,在進程內部啟動之後,可以將自身所在的地址註冊到 etcd。

從而使得 API 網關能夠通過 etcd 及時感知到後端進程的地址,這樣當後端進程發生故障遷移的時候,會重新註冊到 etcd 中,使得 API 網關能夠及時地感知到新的集群地址。同時,因為 etcd 提供的 Lease 操作,可以及時感知到進程狀態的變化,如果進程運行過程中死掉了,那麼網關可以及時感知到進程狀態的變化,從而將流量自動地切到其他的進程。

通過這種方式,整個狀態數據被 etcd 接管,那麼 API 網關本身也是無狀態的,它可以水平地擴展來服務更多的客戶。同時得益於 etcd 的良好性能,可以支持上萬個後端進程的節點,基本上這種架構可以服務於非常大型的企業。

Distributed Coordination: leader election#

第三個場景是分佈式場景中比較常見的一個選主的場景。

我們知道在分佈式系統中,有一種典型的設計模式就是 Master+Slave。通常情況下,Slave 提供了 CPU 內存磁盤以及網絡的各種資源 ,而 Master 用來控制這些資源的協同,Master 內部會存儲一些狀態數據,以及實現一組和業務邏輯相關的控制器,而 Slave 之間會和 Master 保持一個心跳的交互。

典型的分佈式存儲服務以及分佈式計算服務,比如說 Hadoop,HDFS 等等,它們都是採用了類似這樣的設計模式。這樣的設計模式會有一個典型的問題:Master 節點的可用性。當 Master 故障以後,整個集群的服務就被停掉了,沒有辦法再服務用戶的請求。

為了解決這個問題,需要去啟動多個 Master。那麼多個 Master 就會面臨一個問題:誰來提供這個服務?因為通常情況下分佈式系統和 Master 都是有狀態邏輯的,無法允許多個 Master 同時運行。

深入理解 etcd:基於原理解析

可以通過 etcd 來實現選主,將其中的一個 Master 選主成 Leader,負責控制整個集群中所有 Slave 的狀態。被選主的 Leader 可以將自己的 IP 註冊到 etcd 中,使得 Slave 節點能夠及時獲取到當前組件的地址,從而使得系統按照之前單個 Master 節點的方式繼續工作。當 Leader 節點發生異常之後,通過 etcd 能夠選取出一個新的節點成為主節點,並且註冊新的 IP 之後,Slave 又能夠拉取新的主節點的 IP,從而會繼續恢復服務。這一架構,在分佈式系統中,被廣泛使用。

Distributed Coordination 分佈式系統併發控制#

最後來看分佈式協同中的另外一個問題。在分佈式系統中,當我們去執行一些任務,比如說去升級 OS、或者說升級 OS 上的軟件的時候、又或者去執行一些計算任務的時候,通常情況下需要控制任務的併發度。因為任務到了後端服務,通常是有容量瓶頸的。無法在同一個時刻,同時拉起成千上萬的任務。這樣後端的存儲系統或者是網絡資源都是吃不消的。

深入理解 etcd:基於原理解析

因此需要控制任務執行的併發度。在這個設計模式的進程中通過 etcd 提供的一些基本 API 操作來完成分佈式的協同。這樣當第一個進程執行完畢以後,第二個進程就可以開始執行。同時利用 etcd 的進程存活性檢測機制可以做到:當將任務分發給一個進程,但這個進程沒有執行完就已經死掉之後,可以繼續換下一個進程繼續工作。

也就是說,在這個模式中通過 etcd 去實現一個分佈式的信號量,並且它支持能夠自動地剔除掉故障節點。在進程執行過程中,如果進程的運行週期比較長,我們可以將進程運行過程中的一些狀態數據存儲到 etcd,從而使得當進程故障之後且需要恢復到其他地方時,能夠從 etcd 中去恢復一些執行狀態,而不需要重新去完成整個的計算邏輯,以此來加速整個任務的執行效率。

本節總結#

本節課的主要內容就到此為止了,這裡為大家簡單總結一下:

  • 第一部分,為大家介紹了 etcd 項目是如何誕生的,以及在 etcd 發展的過程中它經歷的幾個階段;
  • 第二部分,為大家介紹了 etcd 的架構以及其內部的基本操作接口,在理解 etcd 是如何實現高可用的基礎之上,結合了實踐的方式展示了 etcd 數據的一些基本操作以及其內部的版本管理機制;
  • 第三部分,介紹了三種典型的 etcd 使用場景,以及在對應的場景下,分佈式系統的設計思路。


分享到:


相關文章: