1. 程式人生 > 實用技巧 >Kafka在ZooKeeper中的應用

Kafka在ZooKeeper中的應用

以下是kafka在zookeep中的詳細儲存結構圖:

1.Broker註冊

Kafka是一個分散式的訊息系統。Kafka 叢集包含一個或多個伺服器,伺服器節點稱為broker。雖然Broker是分散式部署並且相互之間獨立執行的,但是還需要一個註冊系統能夠將整個叢集中的Broker伺服器都管理起來。

在ZooKeeper上有一個專門用來進行Broker伺服器列表記錄的節點,下文中我們稱之為“Broker節點”,其節點路徑為/brokers/ids

每個Broker伺服器在啟動時,都會到ZooKeeper上進行註冊,即到Broker節點下建立屬於自己的節點,其節點路徑為/broker/ids/[0...N]。

從上面的節點路徑中,我們可以看出,在Kafka中,我們使用一個全域性唯一的數字來指定每一個Broker伺服器,可以稱其為“Broker ID"。不同的Broker必須使用不同的Broker ID進行註冊。

注意:Broker建立的節點是一個臨時節點,也就是說,一旦這個Broker伺服器宕機或下線後,那麼對應的Broker節點也就被刪除了。

2.Topic註冊

在Kafka中,會將同一個Topic的訊息分成多個分割槽並將其分佈到多個Broker上,這些資訊在ZooKeeper上由專門的節點來記錄,其節點路徑為/brokers/topics。Kafka中的每一個Topic,都會以/brokers/topics/[topic]的形式記錄在這個節點下,例如/brokers/topic/login和/brokers/topics/search等。

Broker伺服器在啟動後,會到對應的Topic節點下注冊自己的Broker ID,並寫入針對該Topic的分割槽總數。

例如,/brokers/topics/login/3 -->2 這個節點表明Broker ID為3的一個Broker伺服器,對於“login”這個topic的訊息,提供了2個分割槽進行訊息儲存。同樣,這個分割槽數節點也是一個臨時節點。

3.生產者負載均衡

由於同一個Topic訊息會被分割槽並將其分佈在多個Broker上,因此,生產者需要將訊息合理地傳送到這些分散式的Broker上,那麼如何實現生產者的負載均衡,Kafka支援傳統的四層負載均衡,也支援Zookeeper方式實現負載均衡。

(1) 四層負載均衡,根據生產者的IP地址和埠來為其確定一個相關聯的Broker。通常,一個生產者只會對應單個Broker,然後該生產者產生的訊息都發往該Broker。這種方式邏輯簡單,每個生產者不需要同其他系統建立額外的TCP連線,只需要和Broker維護單個TCP連線即可。但是,其無法做到真正的負載均衡,因為實際系統中的每個生產者產生的訊息量及每個Broker的訊息儲存量都是不一樣的,如果有些生產者產生的訊息遠多於其他生產者的話,那麼會導致不同的Broker接收到的訊息總數差異巨大,同時,生產者也無法實時感知到Broker的新增和刪除。

(2) 使用Zookeeper進行負載均衡,由於每個Broker啟動時,都會完成Broker註冊過程,生產者會註冊Broker節點的Watcher事件監聽,通過該節點的變化來動態地感知到Broker伺服器列表的變更,這樣就可以實現動態的負載均衡機制。

4.消費者負載均衡

與生產者類似,Kafka中的消費者同樣需要進行負載均衡來實現多個消費者合理的從對應的Broker伺服器上接收訊息。Kafka有消費者分組的概念,每個消費者分組中都包含了若干個消費者,每一條訊息都只會傳送給分組中的一個消費者,不同的消費者分組消費自己特定Topic下面的訊息,互不干擾。因此消費者的負載均衡也可以看作是同一個消費者分組內部的訊息消費策略。

5.訊息消費進度Offset 記錄

在消費者對指定訊息分割槽進行訊息消費的過程中,需要定時地將分割槽訊息的消費進度Offset記錄到Zookeeper上,以便在該消費者進行重啟或者其他消費者重新接管該訊息分割槽的訊息消費後,能夠從之前的進度開始繼續進行訊息消費。Offset在Zookeeper中由一個專門節點進行記錄,其節點路徑為:

/consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]

節點內容就是Offset的值。

6.消費者註冊

消費者伺服器在初始化啟動時加入消費者分組的步驟如下:

1)註冊到消費者分組

每個消費者伺服器啟動時,都會到Zookeeper的指定節點下建立一個屬於自己的消費者節點,例如/consumers/[group_id]/ids/[consumer_id],完成節點建立後,消費者就會將自己訂閱的Topic資訊寫入該臨時節點。

2)對消費者分組中的消費者的變化註冊監聽

每個消費者都需要關注所屬消費者分組中其他消費者伺服器的變化情況,即對/consumers/[group_id]/ids節點註冊子節點變化的Watcher監聽,一旦發現消費者新增或減少,就觸發消費者的負載均衡。

3)對Broker伺服器變化註冊監聽

消費者需要對/broker/ids/[0-N]中的節點進行監聽,如果發現Broker伺服器列表發生變化,那麼就根據具體情況來決定是否需要進行消費者負載均衡。

4)進行消費者負載均衡。

為了讓同一個Topic下不同分割槽的訊息儘量均衡地被多個消費者消費而進行消費者與訊息分割槽分配的過程,通常,對於一個消費者分組,如果組內的消費者伺服器發生變更或Broker伺服器發生變更,會發出消費者負載均衡。

6.補充

早期版本的 kafka 用 ZooKeeper 做 meta 資訊儲存、consumer 的消費狀態、group 的管理以及offset的值。考慮到ZooKeeper本身的一些因素以及整個架構較大概率存在單點問題,新版本中確實逐漸弱化了ZooKeeper的作用。新的consumer使用了kafka內部的group coordination協議,也減少了對ZooKeeper的依賴。

Kafka 0.9版本之後,consumer已經不通過ZooKeeper來實現重平衡。而是使用GroupCoordinator機制。

Coordinator具體介紹可以檢視部落格:https://www.cnblogs.com/zhy-heaven/p/10994022.html