天天看點

ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker?

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實作,經過如下調用鍊:

ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker?
ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker?

該方法裡面,Kafka構造了一個更新中繼資料請求:

ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker?

該方法建立的并不是一個真正的更新中繼資料的MetadataRequest,而是一個用于構造MetadataRequest的構造器MetadataRequest.Builder,等到真正要發送請求之前,Kafka才會調用Builder.buid()方法把這個MetadataRequest建構出來然後發送出去。其實不僅是中繼資料的請求,所有的請求都是這樣處理的。

調用sendInternalMetadataRequest()方法時,這個請求也并沒有被真正發出去,依然是儲存在待發送的隊列中,然後擇機來異步批量發送。

請求的具體資料内容封裝在MetadataRequestData 類

ZooKeeper到底為Kafka的做了什麼犧牲?(上)1 Kafka的zk有什麼作用?2 Kafka client如何定位Broker?