一次 kafka 消息堆積問題排查
- 2020 年 2 月 13 日
- 筆記
收到某業務組的小夥伴發來的回饋,具體問題如下:
項目中某 kafka 消息組消費特別慢,有時候在 kafka-manager 控制台看到有些消費者已被踢出消費組。
從服務端日誌看到如下資訊:

該消費組在短時間內重平衡了 600 多次。
從 cat 查看得知,每條消息處理都會有 4 次資料庫的交互,經過一番溝通之後,發現每條消息的處理耗時大概率保持在 200ms 以上。
Kafka 發生重平衡的有以下幾種情況:
- 消費組成員發生變更,有新消費者加入或者離開,或者有消費者崩潰;
- 消費組訂閱的主題數量發生變更;
- 消費組訂閱的分區數發生變更。
在第 2、3 點都沒有發生的情況下,那麼就是由消費組成員發生了變化導致 Kafka 發生重平衡。
在查看 kafka 客戶端日誌,發現有很多如下日誌:

日誌的描述得知,消費者被被剔除的原因是調用 poll() 方法消費耗時太久了,其中有提到 max.poll.interval.ms 和 max.poll.records 兩個參數,而且還會導致提交
max.poll.interval.ms 表示消費者處理消息邏輯的最大時間,對於某些業務來說,處理消息可能需要很長時間,比如需要 1 分鐘,那麼該參數就需要設置成大於 1分鐘的值,否則就會被 Coordinator 剔除消息組然後重平衡, 默認值為 300000;
max.poll.records 表示每次默認拉取消息條數,默認值為 500。
我們來計算一下:
200 * 500 = 100000 < max.poll.interval.ms =300000,
前面我也講了,當每條消息處理時間大概率會超過 200ms。
結論:
本次出現的問題是由於客戶端的消息消費邏輯耗時太長,如果生產端出現消息發送增多,消費端每次都拉取了 500 條消息進行消費,這時就很容易導致消費時間過長,如果超過了 max.poll.interval.ms 所設置的時間,就會被消費組所在的 coordinator 剔除掉,從而導致重平衡,Kafka 重平衡過程中是不能消費的,會導致消費組處於類似 stop the world 的狀態下,重平衡過程中也不能提交位移,這會導致消息重複消費從而使得消費組的消費速度下降,導致消息堆積。
解決辦法:
根據業務邏輯調整 max.poll.records 與 max.poll.interval.ms 之間的平衡點,避免出現消費者被頻繁踢出消費組導致重平衡。
近期熱文