一次kafka消息堆積問題排查

NO IMAGE

收到某業務組的小夥伴發來的反饋,具體問題如下:

項目中某 kafka 消息組消費特別慢,有時候在 kafka-manager 控制檯看到有些消費者已被踢出消費組。

從服務端日誌看到如下信息:

一次kafka消息堆積問題排查

該消費組在短時間內重平衡了 600 多次。

從 cat 查看得知,每條消息處理都會有 4 次數據庫的交互,經過一番溝通之後,發現每條消息的處理耗時大概率保持在 200ms 以上。

Kafka 發生重平衡的有以下幾種情況:

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

在第 2、3 點都沒有發生的情況下,那麼就是由消費組成員發生了變化導致 Kafka 發生重平衡。

在查看 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 之間的平衡點,避免出現消費者被頻繁踢出消費組導致重平衡。

更多精彩文章請關注作者維護的公眾號「後端進階」,這是一個專注後端相關技術的公眾號。

關注公眾號並回復「後端」免費領取後端相關電子書籍。

歡迎分享,轉載請保留出處。

一次kafka消息堆積問題排查

相關文章

[譯]為何Svelte殺不死React

12道vue高頻原理面試題,你能答出幾道?

SpringBoot系列教程Mybatis+註解整合篇

六年碼農生涯的2019總結:君子坐而論道,少年起而行之