ETCD對比Consul和zooKeeper如何選型
etcd選型對比
前言
對比 Consul, ZooKeeper。選型etcd有那些好處呢?
基本架構和原理
etcd
ETCD是一個分布式、可靠的key-value存儲的分布式系統(tǒng),用于存儲分布式系統(tǒng)中的關鍵數(shù)據(jù);當然,它不僅僅用于存儲,還提供配置共享及服務發(fā)現(xiàn);基于Go語言實現(xiàn) 。
etcd的特點
-
完全復制:集群中的每個節(jié)點都可以使用完整的存檔
-
高可用性:Etcd可用于避免硬件的單點故障或網(wǎng)絡問題
-
一致性:每次讀取都會返回跨多主機的最新寫入
-
簡單:包括一個定義良好、面向用戶的API(gRPC)
-
安全:實現(xiàn)了帶有可選的客戶端證書身份驗證的自動化TLS
-
可靠:使用Raft算法實現(xiàn)了強一致、高可用的服務存儲目錄
etcd 是基于 raft 算法實現(xiàn)的,具體的實現(xiàn)可參見 etcd實現(xiàn)raft源碼解讀
Consul
先放一張 consul 的架構圖
consul 使用的是 Gossip 協(xié)議
Gossip 中文名稱叫流言協(xié)議,它是一種消息傳播協(xié)議。它的核心思想其實源自我們生活中的八卦、閑聊。我們在日常生活中所看到的勁爆消息其實源于兩類,一類是權威機構如國家新聞媒體發(fā)布的消息,另一類則是大家通過微信等社交聊天軟件相互八卦,一傳十,十傳百的結果。
Gossip 協(xié)議的基本工作原理與我們八卦類似,在 Gossip 協(xié)議中,如下圖所示,各個節(jié)點會周期性地選擇一定數(shù)量節(jié)點,然后將消息同步給這些節(jié)點。收到消息后的節(jié)點同樣做出類似的動作,隨機的選擇節(jié)點,繼續(xù)擴散給其他節(jié)點。
Gossip 協(xié)議的基本工作原理與我們八卦類似,在 Gossip 協(xié)議中,如下圖所示,各個節(jié)點會周期性地選擇一定數(shù)量節(jié)點,然后將消息同步給這些節(jié)點。收到消息后的節(jié)點同樣做出類似的動作,隨機的選擇節(jié)點,繼續(xù)擴散給其他節(jié)點。
最終經過一定次數(shù)的擴散、傳播,整個集群的各個節(jié)點都能感知到此消息,各個節(jié)點的數(shù)據(jù)趨于一致。Gossip 協(xié)議被廣泛應用在多個知名項目中,比如 Redis Cluster 集群版,Apache Cassandra,AWS Dynamo。
Consul 天然支持多數(shù)據(jù)中心,但是多數(shù)據(jù)中心內的服務數(shù)據(jù)并不會跨數(shù)據(jù)中心同步,各個數(shù)據(jù)中心的 Server 集群是獨立的,Consul 提供了 Prepared Query 功能,它支持根據(jù)一定的策略返回多數(shù)據(jù)中心下的最佳的服務實例地址,使你的服務具備跨數(shù)據(jù)中心容災。
這里來看下 Prepared Query 查詢的過程:
比如當你的 API 網(wǎng)關收到用戶請求查詢 A 服務,API 網(wǎng)關服務優(yōu)先從緩存中查找 A 服務對應的最佳實例。若無緩存則向 Consul 發(fā)起一個 Prepared Query 請求查詢 A 服務實例,Consul 收到請求后,優(yōu)先返回本數(shù)據(jù)中心下的服務實例。如果本數(shù)據(jù)中心沒有或異常則根據(jù)數(shù)據(jù)中心間 RTT 由近到遠查詢其它數(shù)據(jù)中心數(shù)據(jù),最終網(wǎng)關可將用戶請求轉發(fā)給最佳的數(shù)據(jù)中心下的實例地址。
Consul 支持以下三種模式的讀請求:
-
默認(default)。默認是此模式,絕大部分場景下它能保證數(shù)據(jù)的強一致性。但在老的 Leader 出現(xiàn)網(wǎng)絡分區(qū)被隔離、新的 Leader 被選舉出來的一個極小時間窗口內,可能會導致 stale read。這是因為 Consul 為了提高讀性能,使用的是基于 Lease 機制來維持 Leader 身份,避免了與其他節(jié)點進行交互確認的開銷。
-
強一致性(consistent)。強一致性讀與 etcd 默認線性讀模式一樣,每次請求需要集群多數(shù)節(jié)點確認 Leader 身份,因此相比 default 模式讀,性能會有所下降。
-
弱一致性(stale)。任何節(jié)點都可以讀,無論它是否 Leader??赡茏x取到陳舊的數(shù)據(jù),類似 etcd 的串行讀。這種讀模式不要求集群有 Leader,因此當集群不可用時,只要有節(jié)點存活,它依然可以響應讀請求。
ZooKeeper
ZooKeeper 是一個典型的分布式數(shù)據(jù)一致性解決方案,分布式應用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負載均衡、命名服務、分布式協(xié)調/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能。
ZooKeeper 的有點:
-
順序一致性: 從同一客戶端發(fā)起的事務請求,最終將會嚴格地按照順序被應用到 ZooKeeper 中去。
-
原子性: 所有事務請求的處理結果在整個集群中所有機器上的應用情況是一致的,也就是說,要么整個集群中所有的機器都成功應用了某一個事務,要么都沒有應用。
-
單一系統(tǒng)映像 : 無論客戶端連到哪一個 ZooKeeper 服務器上,其看到的服務端數(shù)據(jù)模型都是一致的。
-
可靠性: 一旦一次更改請求被應用,更改的結果就會被持久化,直到被下一次更改覆蓋。
再來看下 ZooKeeper 的架構圖,圖片摘自 etcd實戰(zhàn)課
ZooKeeper 集群中的所有機器通過一個 Leader 選舉過程來選定一臺稱為 “Leader” 的機器,Leader 既可以為客戶端提供寫服務又能提供讀服務。
除了 Leader 外,F(xiàn)ollower 和 Observer 都只能提供讀服務。Follower 和 Observer 唯一的區(qū)別在于 Observer 機器不參與 Leader 的選舉過程,也不參與寫操作的“過半寫成功”策略,因此 Observer 機器可以在不影響寫性能的情況下提升集群的讀性能。
ZooKeeper 使用的是 Zab 協(xié)議
ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協(xié)議是為分布式協(xié)調服務 ZooKeeper 專門設計的一種支持崩潰恢復的原子廣播協(xié)議。 在 ZooKeeper 中,主要依賴 ZAB 協(xié)議來實現(xiàn)分布式數(shù)據(jù)一致性,基于該協(xié)議,ZooKeeper 實現(xiàn)了一種主備模式的系統(tǒng)架構來保持集群中各個副本之間的數(shù)據(jù)一致性。
Zab 協(xié)議可以分為以下階段:
-
Phase 0,Leader 選舉(Leader Election)。一個節(jié)點只要求獲得半數(shù)以上投票,就可以當選為準 Leader;
-
Phase 1,發(fā)現(xiàn)(Discovery)。準 Leader 收集其他節(jié)點的數(shù)據(jù)信息,并將最新的數(shù)據(jù)復制到自身;
-
Phase 2,同步(Synchronization)。準 Leader 將自身最新數(shù)據(jù)復制給其他落后的節(jié)點,并告知其他節(jié)點自己正式當選為 Leader;
-
Phase 3,廣播(Broadcast)。Leader 正式對外服務,處理客戶端寫請求,對消息進行廣播。當收到一個寫請求后,它會生成 Proposal 廣播給各個 Follower 節(jié)點,一半以上 Follower 節(jié)點應答之后,Leader 再發(fā)送 Commit 命令給各個 Follower,告知它們提交相關提案;
關于 ZAB 中的兩種模式:崩潰恢復和消息廣播
崩潰恢復
當整個服務框架在啟動過程中,或是當 Leader 服務器出現(xiàn)網(wǎng)絡中斷、崩潰退出與重啟等異常情況時,ZAB 協(xié)議就會進人恢復模式并選舉產生新的Leader服務器。
當選出 leader ,并且完成了上面 Phase 2 的同步過程,就退出崩潰恢復模式
消息廣播
當準 Leader 將自身最新數(shù)據(jù)復制給其他落后的節(jié)點,并告知其他節(jié)點自己正式當選為 Leader。這時候就可以進入廣播模式,當有客戶端進行數(shù)據(jù)寫入操作的時候,就可以通過廣播模式通知所有的 follower 了。
當集群中已經有過半的Follower服務器完成了和Leader服務器的狀態(tài)同步,那么整個服務框架就可以進人消息廣播模式了。
選型對比
-
1、并發(fā)原語:etcd 和 ZooKeeper 并未提供原生的分布式鎖、Leader 選舉支持,只提供了核心的基本數(shù)據(jù)讀寫、并發(fā)控制 API,由應用上層去封裝,consul 就簡單多了,提供了原生的支持,通過簡單點命令就能使用;
-
2、服務發(fā)現(xiàn):etcd 和 ZooKeeper 并未提供原生的服務發(fā)現(xiàn)支持,Consul 在服務發(fā)現(xiàn)方面做了很多解放用戶雙手的工作,提供了服務發(fā)現(xiàn)的框架,幫助你的業(yè)務快速接入,并提供了 HTTP 和 DNS 兩種獲取服務方式;
-
3、健康檢查:consul 的健康檢查機制,是一種基于 client、Gossip 協(xié)議、分布式的健康檢查機制,具備低延時、可擴展的特點。業(yè)務可通過 Consul 的健康檢查機制,實現(xiàn) HTTP 接口返回碼、內存乃至磁盤空間的檢測,相比 etcd、ZooKeeper 它們提供的健康檢查機制和能力就非常有限了;
etcd 提供了 Lease 機制來實現(xiàn)活性檢測。它是一種中心化的健康檢查,依賴用戶不斷地發(fā)送心跳續(xù)租、更新 TTL
ZooKeeper 使用的是一種名為臨時節(jié)點的狀態(tài)來實現(xiàn)健康檢查。當 client 與 ZooKeeper 節(jié)點連接斷掉時,ZooKeeper 就會刪除此臨時節(jié)點的 key-value 數(shù)據(jù)。它比基于心跳機制更復雜,也給 client 帶去了更多的復雜性,所有 client 必須維持與 ZooKeeper server 的活躍連接并保持存活。
-
4、watch 特性:相比于 etcd , Consul 存儲引擎是基于Radix Tree實現(xiàn)的,因此它不支持范圍查詢和監(jiān)聽,只支持前綴查詢和監(jiān)聽,而 etcd 都支持, ZooKeeper 的 Watch 特性有更多的局限性,它是個一次性觸發(fā)器;
-
5、線性讀。etcd 和 Consul 都支持線性讀,而 ZooKeeper 并不具備。
-
6、權限機制比較。etcd 實現(xiàn)了 RBAC 的權限校驗,而 ZooKeeper 和 Consul 實現(xiàn)的 ACL。
-
7、事務比較。etcd 和 Consul 都提供了簡易的事務能力,支持對字段進行比較,而 ZooKeeper 只提供了版本號檢查能力,功能較弱。
-
8、多數(shù)據(jù)中心。在多數(shù)據(jù)中心支持上,只有 Consul 是天然支持的,雖然它本身不支持數(shù)據(jù)自動跨數(shù)據(jù)中心同步,但是它提供的服務發(fā)現(xiàn)機制、Prepared Query功能,賦予了業(yè)務在一個可用區(qū)后端實例故障時,可將請求轉發(fā)到最近的數(shù)據(jù)中心實例。而 etcd 和 ZooKeeper 并不支持。
總結
總的看下來,consul 提供了原生的分布式鎖、健康檢查、服務發(fā)現(xiàn)機制支持,讓業(yè)務可以更省心,同時也對多數(shù)據(jù)中心進行了支持;
當然 etcd 和 ZooKeeper 也都有相應的庫,也能很好的進行支持,但是這兩者不支持多數(shù)據(jù)中心;
ZooKeeper 在 Java 業(yè)務中選型使用的較多,etcd 因為是 go 語言開發(fā)的,所以如果本身就是 go 的技術棧,使用這個也是個不錯的選擇,Consul 在國外應用比較多,中文文檔及實踐案例相比 etcd 較少;
參考
【服務發(fā)現(xiàn)框架選型: Consul、Zookeeper還是etcd ?】https://www.cnblogs.com/sunsky303/p/11127324.html
【23 | 選型:etcd/ZooKeeper/Consul等我們該如何選擇?】https://time.geekbang.org/column/article/351898
【服務發(fā)現(xiàn)比較】https://developer.aliyun.com/article/759139
【ZooKeeper講解】https://juejin.cn/post/6844903677367418893