從一個生產上的錯誤看kafka的消費再均衡問題

問題描述

項目在生產上的一段錯誤日誌如下,

[commitSync] processed message to kafka failed, Just Ignore this commit, wait for next commit to make these messages processed.org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed since the group has already rebalanced and assigned the partitions to another member. This means that the time between subsequent calls to poll() was longer than the configured max.poll.interval.ms, which typically implies that the poll loop is spending too much time message processing. You can address this either by increasing the session timeout or by reducing the maximum size of batches returned in poll() with max.poll.records.
		at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$OffsetCommitResponseHandler.handle(ConsumerCoordinator.java:786)

這是一段kafka的錯誤日誌,大概的意思是說,

kafka的服務端在超過了 max.poll.interval.ms 時間內沒有收到某個消費者的心跳,認爲該消費者已經“掛了”,所以進行了topic的分區所有權“再均衡”。

問題的分析

按照我的個人習慣,遇到類似這樣的生產問題,解決之後我會思考下涉及的技術細節並做整理。

如果對問題涉及的技術細節非常的瞭解,對於定位問題是非常有幫助的。本文就帶你深入瞭解下上面那個錯誤日誌涉及的一些技術細節。

kafka的topic分區

爲了提高消息處理的高可用以及便於橫向擴展,kafka引入了topic的分區概念。屬於同一個消費者羣組的消費者可以分擔的消費同一個topic不同分區的消息。從而達到分流的作用,可以使消息處理更高效。

在這裏插入圖片描述

如上圖示例所示,topic A有三個分區,同時我們有三個屬於同一個羣組的消費者,這樣每個消費者可以負責消費一個分區。大家各自負責自己的分區,系統有條不紊的運行着。

一般情況下,我們通過增加羣組裏的消費者數量來提高 kafka 的消費能力。不過要注意,不要讓消費者的數量超過主題分區的數量,多餘的消費者只會被閒置。

心跳機制

kafka 的服務端需要一直監控有哪些消費者在消費,監控的機制是通過消費者不斷的發送心跳包實現的。消費者發送心跳有兩個途徑,一個是輪詢(poll,這裏不是爲了秀英文,注意聯繫上面的錯誤日誌),一個是消費後提交 offset 。

這兩種方式是兩個獨立的線程,互相不干擾。

只要消費者以正常的時間間隔發送心跳,就被認爲是活躍的,說明它還在讀取分區裏的消息,否則就被認爲是已經“死亡”。
這個所謂的正常的時間間隔,就是不能超過 max.poll.interval.ms。

kafka的分區再均衡

消費者通過向服務端發送心跳來維持它們和羣組的從屬關係以及它們對分區的所有權關係。如果服務端認爲某個消費者已經“死亡”,就會觸發一次再均衡。如下圖所示,

在這裏插入圖片描述
前面說過,羣組裏的消費者共同讀取主題的分區。

比如有一個新的消費者加入羣組,它讀取的是原本由其他消費者讀取的消息。當一個消費者被關閉或發生崩潰時,它就離開羣組,原本由它讀取的分區將由羣組裏的其他消費者來讀取。

分區的所有權從一個消費者轉移到另一個消費者,這樣的行爲被稱爲再均衡。

再均衡有什麼意義嗎?

當然,有了再均衡,我們可以放心的添加或者移除某個消費者,而不用擔心消息的丟失。

解決問題

瞭解了相關的技術細節後,我們可以順藤摸瓜,慢慢排查問題。基於前面的分析,我給出幾個排查的方向:

  1. 看看某個消費者的服務是否已經掛了?
  2. 如果服務正常運行,服務所在的節點是否有頻繁FULL GC的情況,或者存在內存或者CPU佔滿的情況,導致消費者無法及時的發送心跳等。我遇到的情況就是這個原因引起的。後來解決了full GC的問題後,kafka的錯誤就不存在了。
  3. 根據自己實際的業務情況,考慮增加 max.poll.interval.ms 的值。

參考:

  1. 《kafka權威指南》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章