最近渠缕,confluent
社區(qū)發(fā)表了一篇文章鸽素,主要講述了Kafka
未來的2.8
版本將要放棄Zookeeper
,這對于Kafka
用戶來說褐健,是一個重要的改進付鹿。之前部署Kafka
就必須得部署Zookeeper
澜汤,而之后就只要單獨部署Kafka
就行了蚜迅。[1]
1.Kafka簡介
Apache Kafka
最早是由Linkedin
公司開發(fā),后來捐獻給了Apack
基金會俊抵。
Kafka
被官方定義為分布式流式處理平臺谁不,因為具備高吞吐、可持久化徽诲、可水平擴展等特性而被廣泛使用刹帕。目前Kafka
具體如下功能:
- 消息隊列,
Kafka
具有系統(tǒng)解耦、流量削峰谎替、緩沖偷溺、異步通信等消息隊列的功能。 - 分布式存儲系統(tǒng)钱贯,
Kafka
可以把消息持久化挫掏,同時用多副本來實現(xiàn)故障轉(zhuǎn)移,可以作為數(shù)據(jù)存儲系統(tǒng)來使用秩命。 - 實時數(shù)據(jù)處理尉共,
Kafka
提供了一些和數(shù)據(jù)處理相關(guān)的組件褒傅,比如Kafka Streams
、Kafka Connect
袄友,具備了實時數(shù)據(jù)的處理功能殿托。
下面這張圖是Kafka
的消息模型:[2]
通過上面這張圖,介紹一下Kafka
中的幾個主要概念:
-
producer
和consumer
: 消息隊列中的生產(chǎn)者和消費者剧蚣,生產(chǎn)者將消息推送到隊列支竹,消費者從隊列中拉取消息。 -
consumer group
:消費者集合鸠按,這些消費者可以并行消費同一個topic
下不同partition
中的消息唾戚。 -
broker
:Kafka
集群中的服務(wù)器。 -
topic
:消息的分類待诅。 -
partition
:topic
物理上的分組叹坦,一個topic
可以有partition
,每個partition
中的消息會被分配一個有序的id
作為offset
卑雁。每個consumer group
只能有一個消費者來消費一個partition
募书。
2.Kafka和Zookeeper關(guān)系
Kafka架構(gòu)如下圖:
Kafka
的工作需要Zookeeper
的配合测蹲。那他們到底是怎么配合工作呢莹捡?看下面這張圖:
2.1 注冊中心
2.1.1 broker注冊
從上面的圖中可以看到,broker
分布式部署扣甲,就需要一個注冊中心來進行統(tǒng)一管理篮赢。Zookeeper
用一個專門節(jié)點保存Broker
服務(wù)列表,也就是 /brokers/ids
琉挖。
broker
在啟動時启泣,向Zookeeper
發(fā)送注冊請求,Zookeeper
會在/brokers/ids
下創(chuàng)建這個broker
節(jié)點示辈,如/brokers/ids/[0...N]
寥茫,并保存broker
的IP
地址和端口。
?這個節(jié)點臨時節(jié)點矾麻,一旦
?broker
宕機纱耻,這個臨時節(jié)點會被自動刪除。
2.1.2 topic注冊
Zookeeper
也會為topic
分配一個單獨節(jié)點险耀,每個topic
都會以/brokers/topics/[topic_name]
的形式記錄在Zookeeper
弄喘。
一個topic
的消息會被保存到多個partition
,這些partition
跟broker
的對應(yīng)關(guān)系也需要保存到Zookeeper
甩牺。
partition
是多副本保存的蘑志,上圖中紅色partition
是leader
副本。當(dāng)leader
副本所在的broker發(fā)生故障時,partition
需要重新選舉leader
卖漫,這個需要由Zookeeper
主導(dǎo)完成费尽。
broker
啟動后,會把自己的Broker ID
注冊到到對應(yīng)topic
節(jié)點的分區(qū)列表中羊始。
我們查看一個topic
是xxx
旱幼,分區(qū)編號是1
的信息,命令如下:
[root@master]?get?/brokers/topics/xxx/partitions/1/state
{"controller_epoch":15,"leader":11,"version":1,"leader_epoch":2,"isr":[11,12,13]}
?當(dāng)
?broker
退出后突委,Zookeeper
會更新其對應(yīng)topic
的分區(qū)列表柏卤。
2.1.3 consumer注冊
消費者組也會向Zookeeper
進行注冊,Zookeeper
會為其分配節(jié)點來保存相關(guān)數(shù)據(jù)匀油,節(jié)點路徑為/consumers/{group_id}
缘缚,有3
個子節(jié)點,如下圖:
Zookeeper
可以記錄分區(qū)跟消費者的關(guān)系敌蚜,以及分區(qū)的offset
桥滨。[3]2.2 負(fù)載均衡
broker
向Zookeeper
進行注冊后,生產(chǎn)者根據(jù)broker
節(jié)點來感知broker
服務(wù)列表變化弛车,這樣可以實現(xiàn)動態(tài)負(fù)載均衡齐媒。
consumer group
中的消費者,可以根據(jù)topic
節(jié)點信息來拉取特定分區(qū)的消息,實現(xiàn)負(fù)載均衡纷跛。
?實際上喻括,
Kafka
在Zookeeper
中保存的元數(shù)據(jù)非常多,看下面這張圖:隨著broker贫奠、topic和partition增多唬血,保存的數(shù)據(jù)量會越來越大。 ?
3.Controller介紹
經(jīng)過上一節(jié)的講述唤崭,我們看到了Kafka
對Zookeeper
的依賴非常大拷恨,Kafka
離開Zookeeper
是沒有辦法獨立運行的。那Kafka
是怎么跟Zookeeper
進行交互的呢浩姥?
如下圖:[4]
Kafka
集群中會有一個broker
被選舉為Controller
負(fù)責(zé)跟Zookeeper
進行交互挑随,它負(fù)責(zé)管理整個Kafka
集群中所有分區(qū)和副本的狀態(tài)。其他broker
監(jiān)聽Controller
節(jié)點的數(shù)據(jù)變化勒叠。Controller
的選舉工作依賴于Zookeeper
,選舉成功后膏孟,Zookeeper
會創(chuàng)建一個/controller
臨時節(jié)點眯分。
Controller
具體職責(zé)如下:
- 監(jiān)聽分區(qū)變化
?比如當(dāng)某個分區(qū)的leader出現(xiàn)故障時,Controller會為該分區(qū)選舉新的leader柒桑。當(dāng)檢測到分區(qū)的ISR集合發(fā)生變化時弊决,Controller會通知所有broker更新元數(shù)據(jù)。當(dāng)某個topic增加分區(qū)時,Controller會負(fù)責(zé)重新分配分區(qū)飘诗。
?
- 監(jiān)聽
topic
相關(guān)的變化 - 監(jiān)聽
broker
相關(guān)的變化 - 集群元數(shù)據(jù)管理
下面這張圖展示了Controller与倡、Zookeeper和broker的交互細節(jié):
Controller
選舉成功后,會從Zookeeper
集群中拉取一份完整的元數(shù)據(jù)初始化ControllerContext
昆稿,這些元數(shù)據(jù)緩存在Controller
節(jié)點纺座。當(dāng)集群發(fā)生變化時,比如增加topic
分區(qū)溉潭,Controller
不僅需要變更本地的緩存數(shù)據(jù)净响,還需要將這些變更信息同步到其他Broker
。Controller
監(jiān)聽到Zookeeper
事件喳瓣、定時任務(wù)事件和其他事件后馋贤,將這些事件按照先后順序暫存到LinkedBlockingQueue
中,由事件處理線程按順序處理畏陕,這些處理多數(shù)需要跟Zookeeper
交互配乓,Controller
則需要更新自己的元數(shù)據(jù)。
4.Zookeeper帶來的問題
Kafka
本身就是一個分布式系統(tǒng)惠毁,但是需要另一個分布式系統(tǒng)來管理扰付,復(fù)雜性無疑增加了。
4.1 運維復(fù)雜度
使用了Zookeeper
仁讨,部署Kafka
的時候必須要部署兩套系統(tǒng)羽莺,Kafka
的運維人員必須要具備Zookeeper
的運維能力。
4.2 Controller故障處理
Kafaka
依賴一個單一Controller
節(jié)點跟Zookeeper
進行交互洞豁,如果這個Controller
節(jié)點發(fā)生了故障盐固,就需要從broker
中選擇新的Controller
。如下圖,新的Controller
變成了broker3
丈挟。
新的Controller
選舉成功后刁卜,會重新從Zookeeper
拉取元數(shù)據(jù)進行初始化,并且需要通知其他所有的broker
更新ActiveControllerId
曙咽。老的Controller
需要關(guān)閉監(jiān)聽蛔趴、事件處理線程和定時任務(wù)。分區(qū)數(shù)非常多時例朱,這個過程非常耗時孝情,而且這個過程中Kafka
集群是不能工作的。
4.3 分區(qū)瓶頸
當(dāng)分區(qū)數(shù)增加時洒嗤,Zookeeper
保存的元數(shù)據(jù)變多箫荡,Zookeeper
集群壓力變大媳友,達到一定級別后骤视,監(jiān)聽延遲增加戈盈,給Kafaka
的工作帶來了影響。
所以液肌,Kafka
單集群承載的分區(qū)數(shù)量是一個瓶頸啥繁。而這又恰恰是一些業(yè)務(wù)場景需要的唱蒸。
5.升級
升級前后的架構(gòu)圖對比如下:
KIP-500
用Quorum Controller
代替之前的Controller
敷矫,Quorum
中每個Controller
節(jié)點都會保存所有元數(shù)據(jù),通過KRaft
協(xié)議保證副本的一致性低矮。這樣即使Quorum Controller
節(jié)點出故障了印叁,新的Controller
遷移也會非常快商佛。
官方介紹喉钢,升級之后,Kafka
可以輕松支持百萬級別的分區(qū)良姆。
?Kafak團隊把通過Raft協(xié)議同步數(shù)據(jù)的方式Kafka Raft Metadata mode,簡稱KRaft
?
Kafka
的用戶體量非常大肠虽,在不停服的情況下升級是必要的。
目前去除Zookeeper
的Kafka
代碼KIP-500
已經(jīng)提交到trunk
分支玛追,并且已經(jīng)在的2.8
版本發(fā)布税课。
Kafaka
計劃在3.0
版本會兼容Zookeeper Controller
和Quorum Controller
,這樣用戶可以進行灰度測試痊剖。[5]
6.總結(jié)
在大規(guī)模集群和云原生的背景下韩玩,使用Zookeeper
給Kafka
的運維和集群性能造成了很大的壓力。去除Zookeeper
是必然趨勢陆馁,這也符合大道至簡的架構(gòu)思想找颓。
Reference
[1]參考1: https://www.confluent.io/blog/kafka-without-zookeeper-a-sneak-peek/
[2]參考2: https://blog.csdn.net/Zidingyi_367/article/details/110490910
[3]參考3: http://www.reibang.com/p/a036405f989c
[4]參考4: https://honeypps.com/mq/kafka-controller-analysis/
[5]參考5: https://mp.weixin.qq.com/s/ev6NM6hptltQBuTaCHJCQQ
本文使用 文章同步助手 同步