在 Apache Kafka 的早期架構中,ZooKeeper 扮演了分布式協調服務角色,負責管理和協調整個 Kafka 集群。 盡管新版本的 Kafka 正在逐步移除對 ZooKeeper 的依賴,但在許多現有和較早的系統中,了解 ZooKeeper 的作用仍然非常重要。
ZooKeeper 在 Kafka 中的核心角色包括:
-
集群成員管理(Broker 注冊): Kafka 集群中的每個 Broker(節點)在啟動時都會向 ZooKeeper 注冊自己的信息,例如 IP 地址和端口。 這種注冊通常是臨時的,意味著如果一個 Broker 宕機或與 ZooKeeper 的連接斷開,它注冊的節點就會被自動刪除。 這使得集群中的其他組件能夠動態地感知到 Broker 的加入或離開。
-
控制器選舉(Controller Election): 集群中會有一個 Broker 被選舉為“控制器”,負責管理分區的狀態、副本的分配以及處理 Broker 的故障轉移。 ZooKeeper 負責這一選舉過程,確保在任何時候集群中只有一個活躍的控制器,避免了“腦裂”問題。
-
元數據存儲: ZooKeeper 是 Kafka 集群元數據的權威存儲中心。 這包括:
- Topic 配置信息: 關于每個 Topic 的分區數量、副本因子、配置覆蓋等信息都存儲在 ZooKeeper 中。
- 分區和副本狀態: ZooKeeper 記錄了每個分區的 Leader 副本是哪個 Broker,以及哪些 Broker 是 Follower 副本(ISR,In-Sync Replicas)。
- 消費者組信息: ZooKeeper 存儲了每個消費者組消費的 Topic,以及每個分區被哪個消費者消費的對應關系。
-
負載均衡: 生產者和消費者客戶端通過監聽 ZooKeeper 中的節點變化,來動態地發現 Broker 列表和 Topic 的分區信息。 當有新的 Broker 加入或有 Broker 宕機時,客戶端能夠及時獲取最新的集群狀態,從而實現生產和消費的負載均衡。
-
消費進度記錄(Offset 存儲): 在舊版本的 Kafka 中,消費者會將其消費每個分區的進度(Offset)定期提交到 ZooKeeper 中進行存儲。 這確保了消費者在重啟或重新分配分區后,可以從上次消費的位置繼續處理消息。不過,新版本的 Kafka 已經將 Offset 的存儲移到了 Kafka 內部的一個名為
__consumer_offsets
的 Topic 中。 -
訪問控制列表(ACLs): Kafka 的安全訪問控制列表信息也存儲在 ZooKeeper 中,用于管理客戶端的讀寫權限。
未來趨勢:移除 ZooKeeper
從 Kafka 2.8.0 版本開始,社區通過 KIP-500 提案引入了基于 Raft 協議的內置共識機制(稱為 KRaft),目標是完全移除對 ZooKeeper 的依賴。 在這種新模式下,Kafka 集群自己管理元數據,從而簡化了部署和運維,并提高了可擴展性和性能。