1. 程式人生 > 其它 >Kafka Rebalance機制和選舉策略

Kafka Rebalance機制和選舉策略

引用:https://www.cnblogs.com/huzhanfei/p/kafka-rebalance-ji-zhi-he-xuan-ju-ce-lue-zong-jie.html

 

Kafka作為大資料領域常用的訊息中介軟體,其核心原理相對於其它訊息中介軟體而言更為複雜,本文主要介紹Kafka消費者的rebalance機制以及controller broker選舉機制、副本選舉機制等實現原理。

Kafka簡易拓撲結構

Kafka核心總控制器Controller

在Kafka叢集中會有一個或者多個broker,其中有一個broker會被選舉為控制器(Kafka Controller),它負責管理整個叢集中所有分割槽和副本的狀態。

  • 當某個分割槽的leader副本出現故障時,由控制器負責為該分割槽選舉新的leader副本。
  • 當檢測到某個分割槽的ISR集合發生變化時,由控制器負責通知所有broker更新其元資料資訊。
  • 當使用kafka-topics.sh指令碼為某個topic增加分割槽數量時,同樣還是由控制器負責分割槽的重新分配。

Controller選舉機制

在kafka叢集啟動的時候,會自動選舉一臺broker作為controller來管理整個叢集,選舉的過程是叢集中每個broker都會嘗試在zookeeper上建立一個/controller臨時節點,zookeeper會保證有且僅有一個broker能建立成功,這個broker就會成為叢集的總控器controller。
當這個controller角色的broker宕機了,此時zookeeper臨時節點會消失,叢集裡其他broker會一直監聽這個臨時節點,發現臨時節點消失了,就競爭再次建立臨時節點,zookeeper又會保證有一個broker成為新的controller。

Controller職責

具備控制器身份的broker需要比其他普通的broker多一份職責,具體細節如下:

  1. 監聽broker相關的變化。為Zookeeper中的/brokers/ids/節點新增BrokerChangeListener,用來處理broker增減的變化。
  2. 監聽topic相關的變化。為Zookeeper中的/brokers/topics節點新增TopicChangeListener,用來處理topic增減的變化;為Zookeeper中的/admin/delete_topics節點新增TopicDeletionListener,用來處理刪除topic的動作。
  3. 從Zookeeper中讀取獲取當前所有與topic、partition以及broker有關的資訊並進行相應的管理。對於所有topic所對應的Zookeeper中的/brokers/topics/[topic]
    節點新增PartitionModificationsListener,用來監聽topic中的分割槽分配變化。
  4. 更新叢集的元資料資訊,同步到其他普通的broker節點中。

Partition Replicates副本選舉機制

controller感知到分割槽leader所在的broker掛了(controller監聽了很多zk節點可以感知到broker存活),controller會從每個parititon的replicas副本列表中取出第一個broker作為leader,當然這個broker需要也同時在ISR列表裡。

Consumer Rebalance機制

消費者消費訊息的offset記錄機制

每個consumer會定期將自己消費分割槽的offset提交給kafka內部topic:__consumer_offsets,提交過去的時候,key是consumerGroupId+topic+分割槽號,value就是當前offset的值,kafka會定期清理topic裡的訊息,最後就保留最新的那條資料,因為__consumer_offsets可能會接收高併發的請求,kafka預設給其分配50個分割槽(可以通過offsets.topic.num.partitions設定),這樣可以通過加機器的方式抗大併發。

消費者Rebalance機制

消費者rebalance發生在如果consumer group中某個消費者掛了,此時會自動把分配給他的分割槽交給其他的消費者,如果他又重啟了,那麼又會把一些分割槽重新交還給他如下情況可能會觸發消費者rebalance,常見的情況如下:

  1. consumer所在服務重啟或宕機了
  2. 動態給topic增加了分割槽
  3. 消費組訂閱了更多的topic

Rebalance過程

當有消費者加入消費組時,消費者、消費組及組協調器之間會經歷以下幾個階段。

第一階段:選擇組協調器

組協調器GroupCoordinator:每個consumer group都會選擇一個broker作為自己的組協調器coordinator,負責監控這個消費組裡的所有消費者的心跳,以及判斷是否宕機,然後開啟消費者rebalance。consumer group中的每個consumer啟動時會向kafka叢集中的某個節點發送FindCoordinatorRequest請求來查詢對應的組協調器GroupCoordinator,並跟其建立網路連線。

組協調器選擇方式:通過如下公式可以選出consumer消費的offset要提交到__consumer_offsets的哪個分割槽,這個分割槽leader對應的broker就是這個consumer group的coordinator

公式hash(consumer group id) % __consumer_offsets主題的分割槽數

第二階段:加入消費組JOIN GROUP

在成功找到消費組所對應的GroupCoordinator之後就進入加入消費組的階段,在此階段的消費者會向GroupCoordinator傳送JoinGroupRequest請求,並處理響應。然後GroupCoordinator從一個consumer group中選擇第一個加入group的consumer作為leader(消費組協調器),把consumer group情況傳送給這個leader,接著這個leader會負責制定分割槽方案(由於rebalance等策略有客戶端配置決定,因此分割槽方案需要consumer來制定,以消費組協調器的配置為準)。

第三階段:SYNC GROUP

consumer leader通過給GroupCoordinator傳送SyncGroupRequest,接著GroupCoordinator就把分割槽方案下發給各個consumer,他們會根據指定分割槽的leader broker進行網路連線以及訊息消費。

消費者Rebalance分割槽分配策略

主要有三種rebalance的策略:rangeround-robinsticky。 Kafka提供了消費者客戶端引數partition.assignment.strategy來設定消費者與訂閱主題之間的分割槽分配策略。

預設情況為range分配策略,假設一個主題有10個分割槽(0-9),現在有三個consumer消費:

    • range策略:按照分割槽序號排序,假設 n=分割槽數/消費者數量=3m=分割槽數%消費者數量 = 1,那麼前m個消費者每個分配n+1個分割槽,後面的(消費者數量-m)個消費者每個分配n個分割槽。比如分割槽0-3給一個consumer,分割槽4-6給一個consumer,分割槽7-9給一個consumer。
    • round-robin策略:輪詢分配,比如分割槽0、3、6、9給一個consumer,分割槽1、4、7給一個consumer,分割槽2、5、8給一個consumer
    • sticky策略:在rebalance的時候,需要保證如下兩個原則。

      1. 分割槽的分配要儘可能均勻。
      2. 分割槽的分配儘可能與上次分配的保持相同。

      sticky策略當兩者發生衝突時,第一個目標優先於第二個目標。
      這樣可以最大程度維持原來的分割槽分配的策略。比如對於第一種range情況的分配,如果第三個consumer掛了,那麼重新用sticky策略分配的結果如下:

      • consumer1除了原有的0~3,會再分配一個7
      • consumer2除了原有的4~6,會再分配8和9