記一次線上kafka一直rebalance故障

今天我司線上kafka消息代理出現錯誤日志,異常rebalance,而且平均間隔2到3分鐘就會rebalance一次,分析日志發現比較嚴重。錯誤日志如下

08-09 11:01:11 131 pool-7-thread-3 ERROR [] - 
commit failed 
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.sendOffsetCommitRequest(ConsumerCoordinator.java:713) ~[MsgAgent-jar-with-dependencies.jar:na]
        at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.commitOffsetsSync(ConsumerCoordinator.java:596) ~[MsgAgent-jar-with-dependencies.jar:na]
        at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:1218) ~[MsgAgent-jar-with-dependencies.jar:na]
        at com.today.eventbus.common.MsgConsumer.run(MsgConsumer.java:121) ~[MsgAgent-jar-with-dependencies.jar:na]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_161]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_161]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]

這個錯誤的意思是,消費者在處理完一批poll的消息后,在同步提交偏移量給broker時報的錯。初步分析日志是由于當前消費者線程消費的分區已經被broker給回收了,因為kafka認為這個消費者死了,那么為什么呢?

分析問題

這里就涉及到問題是消費者在創建時會有一個屬性max.poll.interval.ms
該屬性意思為kafka消費者在每一輪poll()調用之間的最大延遲,消費者在獲取更多記錄之前可以空閑的時間量的上限。如果此超時時間期滿之前poll()沒有被再次調用,則消費者被視為失敗,并且分組將重新平衡,以便將分區重新分配給別的成員。

image.png

如上圖,在while循環里,我們會循環調用poll拉取broker中的最新消息。每次拉取后,會有一段處理時長,處理完成后,會進行下一輪poll。引入該配置的用途是,限制兩次poll之間的間隔,消息處理邏輯太重,每一條消息處理時間較長,但是在這次poll()到下一輪poll()時間不能超過該配置間隔,協調器會明確地讓使用者離開組,并觸發新一輪的再平衡。
max.poll.interval.ms默認間隔時間為300s

分析日志

從日志中我們能看到poll量有時能夠達到250多條


image.png

一次性拉取250多條消息進行消費,而由于每一條消息都有一定的處理邏輯,根據以往的日志分析,每條消息平均在500ms內就能處理完成。然而,我們今天查到有兩條消息處理時間超過了1分鐘。

消息處理日志1

08-09 08:50:05 430 pool-7-thread-3 INFO [] - [RestKafkaConsumer] receive message (收到消息,準備過濾,然后處理), topic: member_1.0.0_event ,partition: 0 ,offset: 1504617
08-09 08:50:05 431 pool-7-thread-3 INFO [] - [RestKafkaConsumer]:解析消息成功,準備請求調用!
08-09 08:51:05 801 pool-7-thread-3 INFO [] - [HttpClient]:response code: {"status":200,"data":{"goodsSendRes":{"status":400,"info":"指>定商品送沒有可用的營銷活動--老pos機"},"fullAmountSendRes":{"status":400,"info":"滿額送沒有可用的營銷活動--老pos機"}},"info":"發券流程執
行成功"}, event:com.today.api.member.events.ConsumeFullEvent, url:https://wechat-lite.today36524.com/api/dapeng/subscribe/index,event內
容:{"id":36305914,"score":16,"orderPrice":15.9,"payTime":1533775401000,"thirdTransId":"4200000160201808

消息處理日志2

08-09 08:51:32 450 pool-7-thread-3 INFO [] - [RestKafkaConsumer] receive message (收到消息,準備過濾,然后處理), topic: member_1.0.0_event ,partition: 0 ,offset: 1504674
08-09 08:51:32 450 pool-7-thread-3 INFO [] - [RestKafkaConsumer]:解析消息成功,準備請求調用!
08-09 08:52:32 843 pool-7-thread-3 INFO [] - [HttpClient]:response code: {"status":200,"data":{"goodsSendRes":{"status":400,"info":"指>定商品送沒有可用的營銷活動--老pos機"},"fullAmountSendRes":{"status":400,"info":"滿額送沒有可用的營銷活動--老pos機"}},"info":"發券流程執
行成功"}, event:com.today.api.member.events.ConsumeFullEvent, url:https://wechat-lite.today36524.com/api/dapeng/subscribe/index,event內
容:{"id":36306061,"score":3,"orderPrice":3.0,"payTime":1533775482000,"thirdTransId":"420000016320180809

我們看到消息消費時間都超過了1分鐘。

分析原因

如下是我們消費者處理邏輯(省略部分代碼)

 while (isRunning) {
            ConsumerRecords<KEY, VALUE> records = consumer.poll(100);
            if (records != null && records.count() > 0) {
           
            for (ConsumerRecord<KEY, VALUE> record : records) {
                dealMessage(bizConsumer, record.value());
                try {
                    //records記錄全部完成后,才提交
                      consumer.commitSync();
                } catch (CommitFailedException e) {
                      logger.error("commit failed,will break this for loop", e);
                        break;
                }
            }
}

poll()方法該方法輪詢返回消息集,調用一次可以獲取一批消息。

kafkaConsumer調用一次輪詢方法只是拉取一次消息。客戶端為了不斷拉取消息,會用一個外部循環不斷調用消費者的輪詢方法。每次輪詢到消息,在處理完這一批消息后,才會繼續下一次輪詢。但如果一次輪詢返回的結構沒辦法及時處理完成,會有什么后果呢?服務端約定了和客戶端max.poll.interval.ms,兩次poll最大間隔。如果客戶端處理一批消息花費的時間超過了這個限制時間,服務端可能就會把消費者客戶端移除掉,并觸發rebalance

拉取偏移量與提交偏移量

kafka的偏移量(offset)是由消費者進行管理的,偏移量有兩種,拉取偏移量(position)與提交偏移量(committed)。拉取偏移量代表當前消費者分區消費進度。每次消息消費后,需要提交偏移量。在提交偏移量時,kafka會使用拉取偏移量的值作為分區的提交偏移量發送給協調者。
如果沒有提交偏移量,下一次消費者重新與broker連接后,會從當前消費者group已提交到broker的偏移量處開始消費。
所以,問題就在這里,當我們處理消息時間太長時,已經被broker剔除,提交偏移量又會報錯。所以拉取偏移量沒有提交到broker,分區又rebalance。下一次重新分配分區時,消費者會從最新的已提交偏移量處開始消費。這里就出現了重復消費的問題。

解決方案

1.增加max.poll.interval.ms處理時長

kafka消費者 默認此間隔時長為300s,本次故障是300s都沒處理完成,于是改成500s。

max.poll.interval.ms=500000

2.設置分區拉取閾值

kafkaConsumer調用一次輪詢方法只是拉取一次消息。客戶端為了不斷拉取消息,會用一個外部循環不斷調用輪詢方法poll()。每次輪詢后,在處理完這一批消息后,才會繼續下一次的輪詢。

max.poll.records = 50

3.poll到的消息,處理完一條就提交一條,當出現提交失敗時,馬上跳出循環,這時候kafka就會進行rebalance,下一次會繼續從當前offset進行消費。

 while (isRunning) {
            ConsumerRecords<KEY, VALUE> records = consumer.poll(100);
            if (records != null && records.count() > 0) {
           
            for (ConsumerRecord<KEY, VALUE> record : records) {
                dealMessage(bizConsumer, record.value());
                try {
                    //records記錄全部完成后,才提交
                      consumer.commitSync();
                } catch (CommitFailedException e) {
                      logger.error("commit failed,will break this for loop", e);
                        break;
                }
            }
}

附錄 查詢日志 某個topic的 partition 的rebalance過程

member_1分區

時間 revoked position revoked committed 時間 assigned
08:53:21 1508667 1508509 08:57:17 1508509
09:16:31 1509187 1508509 09:21:02 1508509
09:23:18 1509323 1508509 09:26:02 1508509
09:35:16 1508509 1508509 09:36:03 1508509
09:36:21 1508509 1508509 09:41:03 1508509
09:42:15 1509323 1508509 09:46:03 1508509
09:47:19 1508509 1508509 09:51:03 1508509
09:55:04 1509323 1509323 09:56:03 1509323
多余消費 被回滾 重復消費 10:01:03 1509323
10:02:20 1510205 1509323 10:06:03 1509323
10:07:29 1509323 1509323 10:08:35 1509323
10:24:43 1509693 1509693 10:25:18 1509693
10:28:38 1510604 1510604 10:35:18 1510604
10:36:37 1511556 1510604 10:40:18 1510604
10:54:26 1511592 1511592 10:54:32 1511592
- - - 10:59:32 1511979
11:01:11 1512178 1512178 11:03:40 1512178
11:04:35 1512245 1512245 11:08:49 1512245
11:12:47 1512407 1512407 11:12:49 1512407
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容