Kafka使用zk實作和RocketMQ的NameServer相似的功能。
1 Kafka的zk有什麼作用?
首先我們來看一下Kafka在ZooKeeper都儲存了哪些資訊:
- 0.8.x的舊版本的情況,最新版本的Kafka已經将消費位置管理等一些原本依賴ZooKeeper實作的功能,替換成了其他的實作方式。
-
ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker? - 綠色框形是臨時節點,其它是持久節點。
1.1 ids 子樹(臨時節點)
儲存的是Kafka的Broker資訊,
/brokers/ids/[0…N]
,每個臨時節點對應一個線上Broker,Broker啟動後會建立一個臨時節點,代表Broker已經加入叢集,可提供服務了,節點名稱就是BrokerID,節點内儲存了包括Broker的位址、版本号、啟動時間等資訊。若Broker當機或與zk叢集失聯,該臨時節點也會消失。
1.2 topics 子樹
topic
儲存topic和partition資訊。
/brokers/topics/
節點下的每個子節點都是一個topic,節點的名稱就是topic名稱。
partitions
每個topic節點下面都包含 一個固定 的partitions節點,pattitions節點的子節點就是主題下的所有分區,節點名稱即分區編号。
state(臨時節點)
位于每個分區節點下,其儲存着 分區目前的leader和所有ISR的BrokerID。該state臨時節點由該分區目前的Leader Broker建立。
若該分區的Leader Broker當機,對應state節點也會消失,直至新Leader被選舉出來,再次建立state節點。
這份中繼資料同時被緩存到每一個Broker。
Kafka主要使用zk儲存其中繼資料、監控Broker和分區的存活狀态,并利用zk進行選舉。
2 Kafka client如何定位Broker?
先根據topic和queue,在topics樹中找到分區對應的state臨時節點。從中取得該Leader的BrokerID,再去ids 子樹,找到BrokerID對應的臨時節點,即可擷取到Broker真正的實體位址。
Kafka client不會直接連zk,而是在需要時,通過RPC請求從Broker拉取所關心的topic的中繼資料,然後儲存到client的中繼資料緩存,以便client的生産和消費。 zk上的中繼資料都是通過Broker中轉給各個Kafka client。
Kafka client(用戶端)真正與Broker(服務端)資料通信是在NetworkClient#poll實作,經過如下調用鍊:
該方法裡面,Kafka構造了一個更新中繼資料請求:
該方法建立的并不是一個真正的更新中繼資料的MetadataRequest,而是一個用于構造MetadataRequest的構造器MetadataRequest.Builder,等到真正要發送請求之前,Kafka才會調用Builder.buid()方法把這個MetadataRequest建構出來然後發送出去。其實不僅是中繼資料的請求,所有的請求都是這樣處理的。
調用sendInternalMetadataRequest()方法時,這個請求也并沒有被真正發出去,依然是儲存在待發送的隊列中,然後擇機來異步批量發送。
請求的具體資料内容封裝在MetadataRequestData 類