深入理解kafka服務端控制器

2021-10-10 10:28:42 字數 2669 閱讀 7018

kafka集群中有1個或者多個broker,其中有乙個broker會被選舉為控制器(kafka controller),它負責管理整個集群中所有分割槽和副本的狀態。

kafka的控制器選舉工作依賴於zookeeper,成功競選為控制器的broker會在zookeeper中建立 /controller 這個臨時節點,該臨時節點內容如下:

zookeeper中節點分為兩種:臨時節點和持久節點

持久節點(persisent):一旦建立,除非主動呼叫刪除操作,否則一直儲存在zk上

臨時節點(ephemeral):與客戶端會話繫結,一旦客戶端會話失效,這個客戶端所建立的所有臨時節點都會被移除

在任意時刻,集群中有且僅有乙個控制器,每個broker 啟動的時候會去嘗試讀取 /controller 節點的 brokerid 的值,如果讀取到brokerid的值不為-1,則表示目前集群中已經存在控制器節點,當前broker 就會放棄競選,如果zookeeper中不存在 /controller 節點,或者這個節點裡的資料異常,那麼這個broker就會嘗試去建立 /controller 節點,可能存在多個broker同時去建立 /controller 節點,但是只有建立成功的那個broker才會成為控制器,其他競選失敗的broker 也會在記憶體中持有控制器brokerid的值,叫做 activecontrollerid。

另外 zookeeper中還有乙個永久節點 /controller_epoch ,用於記錄控制器發生變更的次數:

每個發往控制器的請求,都會攜帶 controller_epoch 這個值,如果請求攜帶的值小於當前記憶體中的 controller_epoch 值,則代表是向已經過期的控制器傳送的請求,這個請求會被認為是無效請求。

由此可見,kafka通過 controller_epoch 這個值來保證控制器的唯一性,進而保證相關操作的一致性。

被選為控制器的broker,相比其他普通broker多了一些功能:

監聽主題相關的變化

監聽broker相關的變化。為zookeper中的/brokers/ids 節點新增brokerchangehandler,用來處理broker增減的變化。

從zookeeper中讀取獲取當前所有與主題、分割槽及broker有關的資訊並進行相應的管理。對所有主題對應的zookeeper中的/brokers/topics/節點新增partitionmodificationshandler,用來監聽主題中的分割槽分配變化。

啟動並管理分割槽狀態機和副本狀態機

更新集群的元資料資訊

如果引數auto.leader.rebalance.enable設定為true,則還會開啟乙個名為

「auto-leader-rebalance-task」的定時任務來負責維護分割槽的優先副本的均衡。

控制器在選舉成功之後會讀取zookeeper中各個節點的資料來初始化上下文資訊(controllercontext),並且需要管理這些上下文資訊。比如為某個主題增加了若干分割槽,控制器在負責建立這些分割槽的同時要更新上下文資訊,並且需要將這些變更資訊同步到其他普通的broker節點中。不管是***觸發的事件,還是定時任務觸發的事件,或者是其他事件(比如controllershutdown)都會讀取或更新控制器中的上下文資訊,那麼這樣就會涉及多執行緒間的同步。如果單純使用鎖機制來實現,那麼整體的效能會大打折扣。針對這一現象,kafka的控制器使用單執行緒基於事件佇列的模型,將每個事件都做一層封裝,然後按照事件發生的先後順序暫存到linkedblockingqueue中,最後使用乙個專用的執行緒controllereventthread 按照fifo的原則順序處理各個事件,這樣不需要鎖機制就可以在多執行緒間維護執行緒安全。

在目前的新版本的設計中,只有kafka controller在zookeeper上註冊相應的***,其他的broker極少需要再監聽zookeeper中的資料變化,這樣省去了很多不必要的麻煩。不過每個broker還是會對 /controller 節點新增***,以此來監聽此節點的資料變化(controllerchangehandler)。

當/controller節點的資料發生變化時,每個broker都會更新自身記憶體中儲存的activecontrollerld。如果 broker 在資料變更前是控制器,在資料變更後自身的brokerid值與新的activecontrollerld值不一致,那麼就需要「退位」,關閉相應的資源,比如關閉狀態機、登出相應的***等。有可能控制器由於異常而下線,造成/controller這個臨時節點被自動刪除;也有可能是其他原因將此節點刪除了。

當/controller節點被刪除時,每個broker都會進行選舉,如果broker在節點被刪除前是控制器,那麼在選舉前還需要有乙個「退位」的動作。如果有特殊需要,則可以手動刪除/controller節點來觸發新一輪的選舉。當然關閉控制器所對應的broker,以及手動向/controller節點寫入新的brokerid的所對應的資料,同樣可以觸發新一輪的選舉。

從服務端架構設計角度,深入理解大型APP架構公升級

1.緊密耦合 無線介面和web應用緊耦合,web端的修改會影響無線介面,web端的發布導致無線介面被動連帶發布,web端的bug影響無線介面的可用性,反過來也一樣,無線介面的任何變化會影響web應用。2.重複開發 3.穩定性 圖二 系統拆分示意 1.對等隔離 2.統一服務 adapter物理上是ja...

深入理解全域性編錄伺服器GC

在win2003ad域環境中,除了fsmo操作主機角色外,全域性編錄伺服器 gc 也是有著特殊含義的網域控制器。通過gc,可以提高在活動目錄中搜尋物件的速度,可以加快使用者登入驗證等。簡單的說,gc是森林中所有物件的唯讀調整緩衝記憶體 read only cache 目錄只用於搜尋。gc伺服器儲存本...

深入理解Redis 伺服器啟動過程

一台redis伺服器從啟動到能夠接收客戶端的命令請求,需要經過一系列的初始化和設定過程,大致需要經過以下幾步。伺服器狀態結構的初始化會建立乙個struct rdisserver型別的例項變數server作為伺服器的狀態,同時為結構中的其他屬性設定預設值。由redis.c initserverconf...