Kafka重平衡機制

  • 2019 年 10 月 11 日
  • 筆記

當集群中有新成員加入,或者某些主題增加了分區之後,消費者是怎麼進行重新分配分區再進行消費的?這裡就涉及到重平衡(Rebalance)的概念,下面我就給大家講解一下什麼是 Kafka 重平衡機制,我盡量做到圖文並茂通俗易懂。

重平衡的作用

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

從圖中可以找到消費組模型的幾個概念:

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

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

Kafka與RocketMQ的重平衡區別

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

Kafka 重平衡:

從圖中可看出,Kafka 重平衡是外部觸發導致的,觸發 Kafka 重平衡的有以下幾種情況:

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

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

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根據分配方案發送給每個消費者。

重平衡場景舉例

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

有新的成員加入消費組:

消費組成員崩潰:

消費組成員主動離開:

消費組成員提交位移時: