Kafka的Controller


控制器組件(Controller),是 Apache Kafka 的核心組件。它的主要作用是在 Apache ZooKeeper 的幫助下管理和協調整個 Kafka 集群。集群中任意一台 Broker 都能充當控制器的角色,但是,在運行過程中,只能有一個 Broker 成為控制器,行使其管理和協調的職責。接下來,我們將討論Controller原理和內部運行機制。通過本文你可以了解到:

  • 什么是Controller Broker
  • Controller Broker是怎么被選舉的
  • Controller Broker主要作用是什么
  • Kafka是如何處理腦裂的

什么是Controller Broker

  在分布式系統中,通常需要有一個協調者,該協調者會在分布式系統發生異常時發揮特殊的作用。在Kafka中該協調者稱之為控制器(Controller),其實該控制器並沒有什么特殊之處,它本身也是一個普通的Broker,只不過需要負責一些額外的工作(追蹤集群中的其他Broker,並在合適的時候處理新加入的和失敗的Broker節點、Rebalance分區、分配新的leader分區等)。值得注意的是:Kafka集群中始終只有一個Controller Broker。

 

Controller Broker是如何被選出來的

  控制器是如何被選出來的呢?當集群啟動后,Kafka 怎么確認控制器位於哪台 Broker 呢?

  實際上,Broker 在啟動時,會嘗試去 ZooKeeper 中創建 /controller 節點。Kafka 當前選舉控制器的規則是:第一個成功創建 /controller 節點的 Broker 會被指定為控制器。先來先當controller

  

 

 

    集群中出現了兩個controller,它們可能一起發出具有沖突的命令,就會出現腦裂的現象。如果對這種情況不加以處理,可能會導致嚴重的不一致。所以需要一種方法來區分誰是集群當前最新的Controller。

    Kafka是通過使用epoch number(紀元編號,也稱為隔離令牌)來完成的。epoch number只是單調遞增的數字,第一次選出Controller時,epoch number值為1,如果再次選出新的Controller,則epoch number將為2,依次單調遞增。

每個新選出的controller通過Zookeeper 的條件遞增操作獲得一個全新的、數值更大的epoch number 。其他Broker 在知道當前epoch number 后,如果收到由controller發出的包含較舊(較小)epoch number的消息,就會忽略它們,即Broker根據最大的epoch number來區分當前最新的controller。

Controller Broker的具體作用是什么

Controller Broker的主要職責有很多,主要是一些管理行為,主要包括以下幾個方面:

  • 創建、刪除主題,增加分區並分配leader分區
  • 集群Broker管理(新增 Broker、Broker 主動關閉、Broker 故障)
  • preferred leader選舉
  • 分區重分配

 

 

處理集群中下線的Broker

當某個Broker節點由於故障離開Kafka群集時,則存在於該Broker的leader分區將不可用(由於客戶端僅對leader分區進行讀寫操作)。為了最大程度地減少停機時間,需要快速找到替代的leader分區。

Controller Broker可以對失敗的Broker做出響應,Controller Broker可以從Zookeeper監聽(zookeeper watch)中獲取通知信息,ZooKeeper 賦予客戶端監控 znode 變更的能力,即所謂的 Watch 通知功能。一旦 znode 節點被創建、刪除,子節點數量發生變化,抑或是 znode 所存的數據本身變更,ZooKeeper 會通過節點變更監聽器 (ChangeHandler) 的方式顯式通知客戶端。

每個 Broker 啟動后,會在zookeeper的 /Brokers/ids 下創建一個臨時 znode。當 Broker 宕機或主動關閉后,該 Broker 與 ZooKeeper 的會話結束,這個 znode 會被自動刪除。同理,ZooKeeper 的 Watch 機制將這一變更推送給控制器,這樣控制器就能知道有 Broker 關閉或宕機了,從而進行后續的協調操作。

Controller將收到通知並對此采取行動,決定哪些Broker上的分區成為leader分區,然后,它會通知每個相關的Broker,要么將Broker上的主題分區變成leader,要么通過LeaderAndIsr請求從新的leader分區中復制數據。

處理新加入到集群中的Broker

通過將Leader分區副本均勻地分布在集群的不同Broker上,可以保障集群的負載均衡。在Broker發生故障時,某些Broker上的分區副本會被選舉為leader,會造成一個Broker上存在多個leader分區副本的情況,由於客戶端只與leader分區副本交互,所以這會給Broker增加額外的負擔,並損害集群的性能和運行狀況。因此,盡快恢復平衡對集群的健康運行是有益的。

Kafka認為leader分區副本最初的分配(每個節點都處於活躍狀態)是均衡的。這些被最初選中的分區副本就是所謂的首選領導者(preferred leaders)。由於Kafka還支持機架感知的leader選舉(rack-aware leader election) ,即嘗試將leader分區和follower分區放置在不同的機架上,以增加對機架故障的容錯能力。因此,leader分區副本的存在位置會對集群的可靠性產生影響。

默認情況下auto.leader.rebalance.enabled為true,表示允許 Kafka 定期地對一些 Topic 分區進行
Leader 重選舉。大部分情況下,Broker的失敗很短暫,這意味着Broker通常會在短時間內恢復。所以當節點離開群集時,與其相關聯的元數據並不會被立即刪除。

當Controller注意到Broker已加入集群時,它將使用Broker ID來檢查該Broker上是否存在分區,如果存在,則Controller通知新加入的Broker和現有的Broker,新的Broker上面的follower分區再次開始復制現有leader分區的消息。為了保證負載均衡,Controller會將新加入的Broker上的follower分區選舉為leader分區。

注意:上面提到的選Leader分區,嚴格意義上是換Leader分區,為了達到負載均衡,可能會造成原來正常的Leader分區被強行變為follower分區。換一次 Leader 代價是很高的,原本向 Leader分區A(原Leader分區) 發送請求的所有客戶端都要切換成向 B (新的Leader分區)發送請求,建議你在生產環境中把這個參數設置成 false。

同步副本(in-sync replica ,ISR)列表

ISR中的副本都是與Leader進行同步的副本,所以不在該列表的follower會被認為與Leader是不同步的. 那么,ISR中存在是什么副本呢?首先可以明確的是:Leader副本總是存在於ISR中。而follower副本是否在ISR中,取決於該follower副本是否與Leader副本保持了“同步”。

始終保證擁有足夠數量的同步副本是非常重要的。要將follower提升為Leader,它必須存在於同步副本列表中。每個分區都有一個同步副本列表,該列表由Leader分區和Controller進行更新。

選擇一個同步副本列表中的分區作為leader 分區的過程稱為clean leader election。注意,這里要與在非同步副本中選一個分區作為leader分區的過程區分開,在非同步副本中選一個分區作為leader的過程稱之為unclean leader election。由於ISR是動態調整的,所以會存在ISR列表為空的情況,通常來說,非同步副本落后 Leader 太多,因此,如果選擇這些副本作為新 Leader,就可能出現數據的丟失。畢竟,這些副本中保存的消息遠遠落后於老 Leader 中的消息。在 Kafka 中,選舉這種副本的過程可以通過Broker 端參數 **unclean.leader.election.enable **控制是否允許 Unclean 領導者選舉。開啟 Unclean 領導者選舉可能會造成數據丟失,但好處是,它使得分區 Leader 副本一直存在,不至於停止對外提供服務,因此提升了高可用性。反之,禁止 Unclean Leader 選舉的好處在於維護了數據的一致性,避免了消息丟失,但犧牲了高可用性。分布式系統的CAP理論說的就是這種情況。

不幸的是,unclean leader election的選舉過程仍可能會造成數據的不一致,因為同步副本並不是完全同步的。由於復制是異步完成的,因此無法保證follower可以獲取最新消息。比如Leader分區的最后一條消息的offset是100,此時副本的offset可能不是100,這受到兩個參數的影響:

    • replica.lag.time.max.ms:同步副本滯后與leader副本的時間
    • zookeeper.session.timeout.ms:與zookeeper會話超時時間

 


免責聲明!

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



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