Kafka 重平衡機制

微信公衆號「後端進階」,專一後端技術分享:Java、Golang、WEB框架、分佈式中間件、服務治理等等。

當集羣中有新成員加入,或者某些主題增長了分區以後,消費者是怎麼進行從新分配消費的?這裏就涉及到重平衡(Rebalance)的概念,下面我就給你們講解一下什麼是 Kafka 重平衡機制,我儘可能作到圖文並茂通俗易懂。後端

重平衡的做用

重平衡跟消費組緊密相關,它保證了消費組成員分配分區能夠作到公平分配,也是消費組模型的實現,消費組模型以下:微信

從圖中能夠找到消費組模型的幾個概念:session

  1. 同一個消費組,一個分區只能被一個消費者訂閱消費,但一個消費者可訂閱多個分區,也便是每條消息只會被同一個消費組的某一個消費者消費,確保不會被重複消費;
  2. 一個分區可被不一樣消費組訂閱,這裏有種特殊狀況,加入每一個消費組只有一個消費者,這樣分區就會廣播到全部消費者上,實現廣播模式消費。

要想實現以上消費組模型,那麼就要實現當外部環境變化時,好比主題新增了分區,消費組有新成員加入等狀況,實現動態調整以維持以上模型,那麼這個工做就會交給 Kafka 重平衡機制去處理。框架

Kafka與RocketMQ的重平衡區別

Kafka 重平衡機制的一些實現相比 RocketMQ 仍是有些區別的,但最終的目的仍是都是同樣,就是保證分區(RocketMQ 是隊列)公平分配且只能被一個消費者訂閱(同一個消費組)。分佈式

Kafka 重平衡:spa

從圖中可看出,Kafka 重平衡是外部觸發致使的,觸發 Kafka 重平衡的有如下幾種狀況:線程

  1. 消費組成員發生變動,有新消費者加入或者離開,或者有消費者崩潰;
  2. 消費組訂閱的主題數量發生變動;
  3. 消費組訂閱的分區數發生變動。

每一個消費者都會跟 Coordinator 保持心跳,當以上狀況發生時,心跳響應就會包含 REBALANCE_IN_PROGRESS 命令,消費者中止消費,加入到重平衡事件當中。3d

RocketMQ重平衡:中間件

RocketMQ 消費者啓動時,會開啓兩條線程,一條線程執行拉取消息任務,另外一條線程者則定時執行重平衡任務,從圖中可看出拉取消息線程會從 pullRequestQueue 中取出拉取任務,pullRequestQueue 是一個阻塞隊列,意味着當 pullRequestQueue 隊列中元素爲空時,會一直阻塞,直到有新的拉取任務,那麼若是添加新的任務到阻塞隊列中去呢?這時 RocketMQ 的重平衡做用就來了,它會每隔 20s 從任意一個 Broker 節點獲取消費組的消費 ID 以及訂閱信息,再根據這些訂閱信息進行分配,而後將分配到的信息封裝成 pullRequest 對象 pull 到 pullRequestQueue 隊列中,拉取線程喚醒後執行拉取任務。對象

重平衡所涉及的參數

在消費者啓動時,某些參數會影響重平衡機制的發生,因此須要根據業務的屬性,對這些參數進行調優,不然可能會由於設置不當致使頻繁重平衡,嚴重影響消費速度,下面跟你們說說這幾個參數的一些要點:

  • session.timeout.ms

該參數是 Coordinator 檢測消費者失敗的時間,即在這段時間內客戶端是否跟 Coordinator 保持心跳,若是該參數設置數值小,能夠更早發現消費者崩潰的信息,從而更快地開啓重平衡,避免消費滯後,可是這也會致使頻繁重平衡,這要根據實際業務來衡量。

  • max.poll.interval.ms

消費者處理消息邏輯的最大時間,對於某些業務來講,處理消息可能須要很長時間,好比須要 1分鐘,那麼該參數就須要設置成大於 1分鐘的值,不然就會被 Coordinator 剔除消息組而後重平衡。

  • heartbeat.interval.ms

該參數跟 session.timeout.ms 緊密關聯,前面也說過,只要在 session.timeout.ms 時間內與 Coordinator 保持心跳,就不會被 Coordinator 剔除,那麼心跳間隔的時間就是 session.timeout.ms,所以,該參數值必須小於 session.timeout.ms,以保持 session.timeout.ms 時間內有心跳。

下面我用圖來形象表達這三個參數的含義:

重平衡流程

在新版本中,消費組的協調管理已經依賴於 Broker 端某個節點,該節點便是該消費組的 Coordinator, 而且每一個消費組有且只有一個 Coordinator,它負責消費組內全部的事務協調,其中包括分區分配,重平衡觸發,消費者離開與剔除等等,整個消費組都會被 Coordinator 管控着,在每一個過程當中,消費組都有一個狀態,Kafka 爲消費組定義了 5 個狀態,以下:

  1. Empty:消費組沒有一個活躍的消費者;
  2. PreparingRebalance:消費組準備進行重平衡,此時的消費組可能已經接受了部分消費者加入組請求;
  3. AwaitingSync:所有消費者都已經加入組而且正在進行重平衡,各個消費者等待 Broker 分配分區方案;
  4. Stable:分區方案已經所有發送給消費者,消費者已經在正常消費;
  5. Dead:該消費組被 Coordinator 完全廢棄。

能夠看出,重平衡發生在 PreparingRebalance 和 AwaitingSync 狀態機中,重平衡主要包括如下兩個步驟:

  1. 加入組(JoinGroup):當消費者心跳包響應 REBALANCE_IN_PROGRESS 時,說明消費組正在重平衡,此時消費者會中止消費,而且發送請求加入消費組;
  2. 同步更新分配方案:當 Coordinator 收到全部組內成員的加入組請求後,會選出一個consumer Leader,而後讓consumer Leader進行分配,分配完後會將分配方案放入SyncGroup請求中發送會Coordinator,Coordinator根據分配方案發送給每一個消費者。

重平衡場景舉例

根據重平衡觸發的條件,重平衡的工做流程大概有如下幾種類型:

有新的成員加入消費組:

消費組成員崩潰

消費組成員主動離開

消費組成員提交位移時

公衆號「後端進階」,專一後端技術分享!

關注公衆號回覆關鍵字「後端」免費領取後端開發大禮包!
相關文章
相關標籤/搜索