- ZooKeeper 的作用
-
那為什么要拋棄 ZooKeeper
- 先來看看運維的層面的問題。
- 再看性能層面的問題。
- 基于 ZooKeeper 的性能問題 Kafka 之前就做了一些升級。
- 所以沒了 Zookeeper 之后的 Kafka 的怎樣的?
- 最后
在上個月 30 號, confluent 發(fā)布了一篇文章,文章上說在 Kafka 2.8 版本上將支持內(nèi)部的 quorum 服務(wù)來替換 ZooKeeper 的工作。
其實去年我寫的 Kafka 控制器事件處理全流程這篇文章已經(jīng)提到這一點。
今天再稍微展開來說說。
ZooKeeper 的作用
ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù)框架,你也可以認為它是一個可以保證一致性的分布式(小量)存儲系統(tǒng)。特別適合存儲一些公共的配置信息、集群的一些元數(shù)據(jù)等等。
它有持久節(jié)點和臨時節(jié)點,而臨時節(jié)點這個玩意再配合 Watcher 機制就很有用。
當創(chuàng)建臨時節(jié)點的客戶端與 ZooKeeper 斷連之后,這個臨時節(jié)點就會消失,并且訂閱了節(jié)點狀態(tài)變更的客戶端會收到這個節(jié)點狀態(tài)變更的通知。
所以集群中某一服務(wù)上線或者下線,都可以被檢測到。因此可以用來實現(xiàn)服務(wù)發(fā)現(xiàn),也可以實現(xiàn)故障轉(zhuǎn)移的監(jiān)聽機制。
Kafka 就是強依賴于 ZooKeeper,沒有 ZooKeeper 的話 Kafka 都無法運行。ZooKeeper 為 Kafka 提供了元數(shù)據(jù)的管理,例如一些 Broker 的信息、主題數(shù)據(jù)、分區(qū)數(shù)據(jù)等等。
在每個 Broker 啟動的時候,都會和 ZooKeeper 進行交互,這樣 ZooKeeper 就存儲了集群中所有的主題、配置、副本等信息。
還有一些選舉、擴容等機制也都依賴 ZooKeeper 。
例如控制器的選舉:每個 Broker 啟動都會嘗試在 ZooKeeper 注冊/controller臨時節(jié)點來競選控制器,第一個創(chuàng)建/controller節(jié)點的 Broker 會被指定為控制器。
競爭失敗的節(jié)點也會依賴 watcher 機制,監(jiān)聽這個節(jié)點,如果控制器宕機了,那么其它 Broker 會繼續(xù)來爭搶,實現(xiàn)控制器的 failover。
從上面就可以得知 ZooKeeper 對 Kafka 來說很重要 。
基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
- 項目地址:https://github.com/YunaiV/ruoyi-vue-pro
- 視頻教程:https://doc.iocoder.cn/video/
那為什么要拋棄 ZooKeeper
軟件架構(gòu)都是演進的,之所以要變更那肯定是因為出現(xiàn)了瓶頸。
先來看看運維的層面的問題。
首先身為一個中間件,需要依賴另一個中間件,這就感覺有點奇怪。
你要說依賴 Netty 這種,那肯定是沒問題的。但是 Kafka 的運行需要提供 ZooKeeper 集群,這其實有點怪怪的。
就等于如果你公司要上 Kafka 就得跟著上 ZooKeeper ,被動了增加了運維的復雜度。
好比你去商場買衣服,要買個上衣,服務(wù)員說不單賣,要買就得買一套,這錢是不是多花了?
所以運維人員不僅得照顧 Kafka 集群,還得照顧 ZooKeeper 集群。
再看性能層面的問題。
ZooKeeper 有個特點,強一致性 。
如果 ZooKeeper 集群的某個節(jié)點的數(shù)據(jù)發(fā)生變更,則會通知其它 ZooKeeper 節(jié)點同時執(zhí)行更新,就得等著大家(超過半數(shù))都寫完了才行,這寫入的性能就比較差了。
然后看到上面我說的小量 存儲系統(tǒng)了吧,一般而言,ZooKeeper 只適用于存儲一些簡單的配置或者是集群的元數(shù)據(jù),不是真正意義上的存儲系統(tǒng)。
如果寫入的數(shù)據(jù)量過大,ZooKeeper 的性能和穩(wěn)定性就會下降,可能導致 Watch 的延時或丟失。
所以在 Kafka 集群比較大,分區(qū)數(shù)很多的時候,ZooKeeper 存儲的元數(shù)據(jù)就會很多,性能就差了。
還有,ZooKeeper 也是分布式的,也需要選舉,它的選舉也不快,而且發(fā)生選舉的那段時候是不提供服務(wù)的!
基于 ZooKeeper 的性能問題 Kafka 之前就做了一些升級。
例如以前 Consumer 的位移數(shù)據(jù)是保存在 ZooKeeper 上的,所以當提交位移或者獲取位移的時候都需要訪問 ZooKeeper ,這量一大 ZooKeeper 就頂不住。
所以后面引入了位移主題(Topic 是 __consumer_offsets),將位移的提交和獲取當做消息一樣來處理,存儲在日志中,避免了頻繁訪問 ZooKeeper 性能差的問題。
還有像一些大公司,可能要支持百萬分區(qū)級別,這目前的 Kafka 單集群架構(gòu)下是無法支持穩(wěn)定運行的,也就是目前單集群可以承載的分區(qū)數(shù)有限。
所以,Kafka 需要去 ZooKeeper 。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
所以沒了 Zookeeper 之后的 Kafka 的怎樣的?
沒了 Zookeeper 的 Kafka 就把元數(shù)據(jù)存儲到自己內(nèi)部了,利用之前的 Log 存儲機制來保存元數(shù)據(jù)。
就和上面說到的位移主題一樣,會有一個元數(shù)據(jù)主題,元數(shù)據(jù)會像普通消息一樣保存在 Log 中。
所以元數(shù)據(jù)和之前的位移一樣,利用現(xiàn)有的消息存儲機制稍加改造來實現(xiàn)了功能,完美!
然后還搞了個 KRaft 來實現(xiàn) Controller Quorum。
圖來自 confluent
這個協(xié)議是基于 Raft 的,協(xié)議具體就不展開了,就理解為它能解決 Controller Leader 的選舉,并且讓所有節(jié)點達成共識。
在之前基于 Zookeeper 實現(xiàn)的單個 Controller 在分區(qū)數(shù)太大的時候還有個問題,故障轉(zhuǎn)移太慢了。
當 Controller 變更的時候,需要重新加載所有的元數(shù)據(jù)到新的 Controller 身上,并且需要把這些元數(shù)據(jù)同步給集群內(nèi)的所有 Broker。
而 Controller Quorum 中的 Leader 選舉切換則很快,因為元數(shù)據(jù)都已經(jīng)在 quorum 中同步了,也就是 quorum 的 Broker 都已經(jīng)有全部了元數(shù)據(jù),所以不需要重新加載元數(shù)據(jù)!
并且其它 Broker 已經(jīng)基于 Log 存儲了一些元數(shù)據(jù),所以只需要增量更新即可,不需要全量了。
這波改造下來就解決了之前元數(shù)據(jù)過多的問題,可以支持更多的分區(qū)!
最后
可能看到這里有人會說,那為何一開始不這么實現(xiàn)?
因為 ZooKeeper 是一個功能強大且經(jīng)過驗證的工具,在早期利用它來實現(xiàn)一些功能,多簡單喲,都不需要自己實現(xiàn)。
要不是 ZooKeeper 的機制導致了這個瓶頸,也不可能會有這個改造的。
軟件就是這樣,沒必要重復造輪子,合適就好。
審核編輯 :李倩
-
控制器
+關(guān)注
關(guān)注
112文章
16103瀏覽量
177074 -
存儲系統(tǒng)
+關(guān)注
關(guān)注
2文章
402瀏覽量
40823 -
kafka
+關(guān)注
關(guān)注
0文章
50瀏覽量
5202
原文標題:總監(jiān)問我:Kafka 為什么要拋棄 ZooKeeper?
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論