微信公衆號「後端進階」,專一後端技術分享:Java、Golang、WEB框架、分佈式中間件、服務治理等等。後端
當集羣中有新成員加入,或者某些主題增長了分區以後,消費者是怎麼進行從新分配消費的?這裏就涉及到重平衡(Rebalance)的概念,下面我就給你們講解一下什麼是 Kafka 重平衡機制,我儘可能作到圖文並茂通俗易懂。微信
重平衡跟消費組緊密相關,它保證了消費組成員分配分區能夠作到公平分配,也是消費組模型的實現,消費組模型以下:session
從圖中能夠找到消費組模型的幾個概念:框架
要想實現以上消費組模型,那麼就要實現當外部環境變化時,好比主題新增了分區,消費組有新成員加入等狀況,實現動態調整以維持以上模型,那麼這個工做就會交給 Kafka 重平衡機制去處理。分佈式
Kafka 重平衡機制的一些實現相比 RocketMQ 仍是有些區別的,但最終的目的仍是都是同樣,就是保證分區(RocketMQ 是隊列)公平分配且只能被一個消費者訂閱(同一個消費組)。線程
Kafka 重平衡:3d
從圖中可看出,Kafka 重平衡是外部觸發致使的,觸發 Kafka 重平衡的有如下幾種狀況:cdn
每一個消費者都會跟 Coordinator 保持心跳,當以上狀況發生時,心跳響應就會包含 REBALANCE_IN_PROGRESS 命令,消費者中止消費,加入到重平衡事件當中。中間件
RocketMQ重平衡:對象
RocketMQ 消費者啓動時,會開啓兩條線程,一條線程執行拉取消息任務,另外一條線程者則定時執行重平衡任務,從圖中可看出拉取消息線程會從 pullRequestQueue 中取出拉取任務,pullRequestQueue 是一個阻塞隊列,意味着當 pullRequestQueue 隊列中元素爲空時,會一直阻塞,直到有新的拉取任務,那麼若是添加新的任務到阻塞隊列中去呢?這時 RocketMQ 的重平衡做用就來了,它會每隔 20s 從任意一個 Broker 節點獲取消費組的消費 ID 以及訂閱信息,再根據這些訂閱信息進行分配,而後將分配到的信息封裝成 pullRequest 對象 pull 到 pullRequestQueue 隊列中,拉取線程喚醒後執行拉取任務。
在消費者啓動時,某些參數會影響重平衡機制的發生,因此須要根據業務的屬性,對這些參數進行調優,不然可能會由於設置不當致使頻繁重平衡,嚴重影響消費速度,下面跟你們說說這幾個參數的一些要點:
該參數是 Coordinator 檢測消費者失敗的時間,即在這段時間內客戶端是否跟 Coordinator 保持心跳,若是該參數設置數值小,能夠更早發現消費者崩潰的信息,從而更快地開啓重平衡,避免消費滯後,可是這也會致使頻繁重平衡,這要根據實際業務來衡量。
消費者處理消息邏輯的最大時間,對於某些業務來講,處理消息可能須要很長時間,好比須要 1分鐘,那麼該參數就須要設置成大於 1分鐘的值,不然就會被 Coordinator 剔除消息組而後重平衡。
該參數跟 session.timeout.ms 緊密關聯,前面也說過,只要在 session.timeout.ms 時間內與 Coordinator 保持心跳,就不會被 Coordinator 剔除,那麼心跳間隔的時間就是 session.timeout.ms,所以,該參數值必須小於 session.timeout.ms,以保持 session.timeout.ms 時間內有心跳。
下面我用圖來形象表達這三個參數的含義:
在新版本中,消費組的協調管理已經依賴於 Broker 端某個節點,該節點便是該消費組的 Coordinator, 而且每一個消費組有且只有一個 Coordinator,它負責消費組內全部的事務協調,其中包括分區分配,重平衡觸發,消費者離開與剔除等等,整個消費組都會被 Coordinator 管控着,在每一個過程當中,消費組都有一個狀態,Kafka 爲消費組定義了 5 個狀態,以下:
能夠看出,重平衡發生在 PreparingRebalance 和 AwaitingSync 狀態機中,重平衡主要包括如下兩個步驟:
根據重平衡觸發的條件,重平衡的工做流程大概有如下幾種類型:
有新的成員加入消費組:
消費組成員崩潰
消費組成員主動離開
消費組成員提交位移時
關注公衆號回覆關鍵字「後端」免費領取後端開發大禮包!