Kafka 入門(三)--為什么 Kafka 依賴 ZooKeeper?


一、ZooKeeper 簡介

1.基本介紹

  ZooKeeper 的官網是:https://zookeeper.apache.org/。在官網上是這么介紹 ZooKeeper 的:ZooKeeper 是一項集中式服務,用於維護配置信息,命名,提供分布式同步和提供組服務。

  當我們編寫程序的時候,通常會將所有的配置信息保存在一個配置文件中,例如賬號、密碼等信息,后續直接修改配置文件就行了,那分布式場景下如何配置呢?如果說每台機器上都保存一個配置文件,這時候要一台台的去修改配置文件難免出錯,而且要管理這些機器也會變得復雜和困難,ZooKeeper 的出現就是為了解決這類問題,實現高度可靠的分布式系統。

2.基本功能

1)配置管理

  ZooKeeper 為分布式系統提供了一種配置管理的服務:集中管理配置,即將全局配置信息保存在 ZooKeeper 服務中,方便進行修改和管理,省去了手動拷貝配置的過程,同時還保證了可靠和一致性。

  

2)命名服務

  在分布式系統中,經常需要對應用或者服務進行統一命名,便於識別和區分開來,而 ZooKeeper 就提供了這種服務。

3)分布式鎖

  鎖應該都不陌生,沒有用過也聽說過,在多個進程訪問互斥資源的時候,需要加上一道鎖。在分布式系統中,分布式程序分布在各個主機上的進程對互斥資源進行訪問時也需要加鎖。

  分布式鎖應當具備以下條件:

  • 在分布式系統環境下,一個方法在同一時間只能被一個機器的一個線程執行;
  • 高可用的獲取鎖與釋放鎖;
  • 高性能的獲取鎖與釋放鎖;
  • 具備可重入特性(可理解為重新進入,由多於一個任務並發使用,而不必擔心數據錯誤);
  • 具備鎖失效機制,防止死鎖;
  • 具備非阻塞鎖特性,即沒有獲取到鎖將直接返回獲取鎖失敗。

4)集群管理

  在分布式系統中,由於各種各樣的原因,例如機器故障、網絡故障等,導致集群中的節點增加或者減少,集群中有些機器需要感知到這種變化,然后根據這種變化做出對應的決策。

3.基本架構

  ZooKeeper 的基本架構圖如下:

  

  我們需要知道以下幾點:

  • Client 表示客戶端,是請求發送方,數量不限;
  • Server 表示服務端,是請求接收方,數量不限;
  • Client 可以連接到每個 Server,每個 Server 中的數據都是一樣的;
  • ZooKeeper 啟動時,會從所有 Server 中選取一個作為 leader(Paxos 協議),每個 follower 都會和 leader 建立連接;
  • leader 負責進行數據更新等操作,並將數據同步到 follower 中,以此實現數據一致性。

4.ZooKeeper節點

  我們使用 znode 來明確表示 ZooKeeper 的數據節點。下圖表示的是 ZooKeeper 的命名層次空間,名稱是由斜杠(/)分隔的一系列路徑元素。

  

  znode 有四種類型 :

1)PERSISTENT(持久節點

  默認的節點類型。持久化保存的節點,創建節點的客戶端與 ZooKeeper 斷開連接后,該節點依舊存在 。

2)PERSISTENT_SEQUENTIAL(持久順序節點)

  所謂順序節點,就是在創建節點時,ZooKeeper 根據創建的時間順序給該節點名稱進行編號,適合用於分布式鎖、分布式選舉等場景。創建時添加 -s 參數即可。

3)EPHEMERAL(臨時節點)

  和持久節點相反,當創建節點的客戶端與 ZooKeeper 斷開連接后,臨時節點會自動刪除,適用於心跳、服務發現等場景。創建時添加參數-e 即可。

4)EPHEMERAL_SEQUENTIAL(臨時順序節點)

  顧名思義,該類節點結合了臨時節點和順序節點的特征,在創建節點時,ZooKeeper 根據創建的時間順序給該節點名稱進行編號,當創建節點的客戶端和 ZooKeeper 斷開連接后,節點自動刪除。創建時添加 -e -s 參數即可。

  ZooKeeper 實現分布式鎖就是利用了臨時順序節點。

  首先在 ZooKeeper 中創建一個持久節點 ParentLock,每當有客戶端想要獲得鎖時,就在 ParentLock 下創建一個臨時順序節點,如果該節點是第一個,則獲得鎖,如果不是,則找到排序比它靠前的一個節點並注冊 Watcher,用於監聽節點是否存在。若第一個節點運行完畢,其客戶端會調用指令刪除該節點,或者其客戶端崩潰,第一個節點也會自動刪除,而第二個節點監聽到該節點被刪除,再經過查詢確認就能獲得鎖了。不難發現 ZooKeeper 實現的分布式鎖相當於是一個等待鎖的隊列,能夠提升搶鎖的效率,但是因為需要創建和刪除節點,導致性能較低。

 

二、Kafka + ZooKeeper

  ZooKeeper 作為給分布式系統提供協調服務的工具被 kafka 所依賴。在分布式系統中,消費者需要知道有哪些生產者是可用的,而如果每次消費者都需要和生產者建立連接並測試是否成功連接,那效率也太低了,顯然是不可取的。而通過使用 ZooKeeper 協調服務,Kafka 就能將 Producer,Consumer,Broker 等結合在一起,同時借助 ZooKeeper,Kafka 就能夠將所有組件在無狀態的條件下建立起生產者和消費者的訂閱關系,實現負載均衡。

  

1)Broker 信息

  在 ZooKeeper 上會有一個專門用來進行 Broker 服務器列表記錄的節點,節點路徑為 /brokers/ids。Kafka 的每個 Broker 啟動時,都會在 ZooKeeper 中注冊,創建 /brokers/ids/[0-N] 節點,寫入 IP,端口等信息,每個 Broker 都有一個 BrokerId。Broker 創建的是臨時節點,在連接斷開時節點就會自動刪除,所以在 ZooKeeper 上就可以通過 Broker 中節點的變化來得到 Broker 的可用性。

2)Topic 信息

  在 Kafka 中可以定義很多個 Topic,每個 Topic 又被分為很多個 Partition。一般情況下,每個 Partition 獨立在存在一個 Broker 上,所有的這些 Topic 和 Broker 的對應關系都由 ZooKeeper 進行維護。

3)負載均衡

  生產者需要將消息發送給 Broker,消費者需要從 Broker 上獲取消息,通過使用 ZooKeeper,就都能監聽 Broker 上節點的狀態信息,從而實現動態負載均衡。

4)offset 信息

  在上一篇博客中提到過,offset 用於記錄消費者消費到的位置,在老版本(0.9以前)里 offset 是保存在 ZooKeeper 中的。

5)Controller 選舉

  在 Kafka 中會有多個 Broker,其中一個 Broker 會被選舉成為 Controller(控制器),在任意時刻,Kafka 集群中有且僅有一個控制器。Controller 負責管理集群中所有分區和副本的狀態,當某個分區的 leader 副本出現故障時,由 Controller 為該分區選舉出一個新的 leader。Kafka 的 Controller 選舉就依靠 ZooKeeper 來完成,成功競選為 Controller 的 Broker 會在 ZooKeeper 中創建 /controller 這個臨時節點,在 ZooKeeper 中使用 get 命令查看節點內容:

  

  其中“version”在目前版本中固定為1,“brokerid”表示 Broker 的編號,“timestamp”表示競選稱為 Controller 時的時間戳。 

  當 Broker 啟動時,會嘗試讀取 /controller 中的“brokerid ”,如果讀取到的值不是-1,則表示已經有節點競選成為 Controller 了,當前節點就會放棄競選;而如果讀取到的值為-1,ZooKeeper 就會嘗試創建 /controller 節點,當該 Broker 去創建的時候,可能還有其他 Broker 一起同時創建節點,但只有一個 Broker 能夠創建成功,即成為唯一的 Controller。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM