簡體   English   中英

Kafka 消費者 CommitFailedException

[英]Kafka Consumer CommitFailedException

我正在研究 kafka 消費者程序。 最近我們將其部署在 PROD 環境中。 在那里我們遇到了如下問題:

[main] INFO com.cisco.kafka.consumer.RTRKafkaConsumer - No. of records fetched: 1
[kafka-coordinator-heartbeat-thread | otm-opl-group] INFO org.apache.kafka.clients.consumer.internals.AbstractCoordinator - [Consumer clientId=consumer-otm-opl-group-1, groupId=otm-opl-group] Group coordinator opl-kafka-prd2-01:9092 (id: 2147483644 rack: null) is unavailable or invalid, will attempt rediscovery
[kafka-coordinator-heartbeat-thread | otm-opl-group] INFO org.apache.kafka.clients.consumer.internals.AbstractCoordinator - [Consumer clientId=consumer-otm-opl-group-1, groupId=otm-opl-group] Discovered group coordinator opl-kafka-prd2-01:9092 (id: 2147483644 rack: null)
[kafka-coordinator-heartbeat-thread | otm-opl-group] INFO org.apache.kafka.clients.consumer.internals.AbstractCoordinator - [Consumer clientId=consumer-otm-opl-group-1, groupId=otm-opl-group] Attempt to heartbeat failed for since member id consumer-otm-opl-group-1-953dfa46-9ced-472f-b24f-36d78c6b940b is not valid.
[main] INFO com.cisco.kafka.consumer.RTRKafkaConsumer - Batch start offset: 9329428
[main] INFO com.cisco.kafka.consumer.RTRKafkaConsumer - Batch Processing Successful.
[main] INFO org.apache.kafka.clients.consumer.internals.ConsumerCoordinator - [Consumer clientId=consumer-otm-opl-group-1, groupId=otm-opl-group] Failing OffsetCommit request since the consumer is not part of an active group
Exception in thread "main" 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 max.poll.interval.ms 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:1061)
    at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.commitOffsetsSync(ConsumerCoordinator.java:936)
    at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:1387)
    at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:1349)
    at com.cisco.kafka.consumer.RTRKafkaConsumer.main(RTRKafkaConsumer.java:72)

我的理解是,當組協調器不可用並重新發現時,心跳間隔(根據文檔為 3 秒)到期,消費者被踢出組。 這樣對嗎?。 如果是這樣,應該解決什么問題? 如果我錯了,請幫助我理解這個問題,並提出解決這個問題的任何想法。 如果需要,我可以分享代碼。

您所指的異常

Exception in thread "main" 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 max.poll.interval.ms or by reducing the maximum size of batches returned in poll() with max.poll.records.

提示正在發生的事情以及可以采取哪些措施來解決問題。 代碼中,這個異常被描述為

“當使用 KafkaConsumer#commitSync() 的偏移提交失敗並出現不可恢復的錯誤時,會引發此異常。當在成功應用提交之前組重新平衡完成時,可能會發生這種情況。在這種情況下,通常無法重試提交,因為某些分區可能已分配給組中的另一個成員。”

根據我的經驗,拋出的錯誤消息可能是由不同的事情引起的,盡管它們都與不再分配給分區的使用者有關:

  1. 在不關閉消費者的情況下創造越來越多的消費者
  2. 投票超時
  3. 心跳超時
  4. 過時的 Kerberos 票證

1. 在不關閉的情況下打開越來越多的消費者

如果您將消費者添加到現有 ConsumerGroup,則會發生重新平衡。 因此,必須在使用后關閉消費者或始終使用相同的實例,而不是為每個消息/迭代創建新的 KafkaConsumer 對象。

2. 輪詢超時(如錯誤消息中所述):

[...] 對 poll() 的后續調用之間的時間比配置的max.poll.interval.ms ,這通常意味着輪詢循環花費了太多時間處理消息。

配置max.poll.interval.ms默認為300000ms5minutes 由於您的使用者花費的時間超過這 5 分鍾,因此該使用者被視為失敗,組將重新平衡以將分區重新分配給另一個成員(請參閱使用者配置)。

輪詢超時的解決方案:

錯誤信息中也給出了一個可能的解決方案

您可以通過增加max.poll.interval.ms或通過使用max.poll.interval.ms減少 poll() 中返回的批次的最大大小來解決此max.poll.records

消費者再次讀取所有消息,因為(如錯誤所示)它無法提交偏移量。 這意味着,如果您使用相同的group.id啟動 Consumer,它會認為它從未從該主題中讀取任何內容。

3.心跳超時

KafkaConsumer 中有兩個主要配置處理心跳: heartbeat.interval.mssession.timeout.ms

在單獨的后台線程中,您的 KafkaConsumer 會定期向服務器發送心跳。 如果消費者在 session.timeout.ms 時間內崩潰或無法發送心跳,則消費者將被視為死亡,其分區將被重新分配。 如果觸發了重新平衡,您的使用者將無法從“舊分配”分區提交任何內容,如 CommitFailedException 的描述中所寫:“這可能發生在組重新平衡在成功應用提交之前完成時。”

心跳超時的解決方法:

在遵循以下建議的同時增加設置heartbeat.interval.mssession.timeout.ms :“ heartbeat.interval.ms必須設置為低於session.timeout.ms ,但通常不應設置為高於該值的 1/3價值。”

請記住,更改這些值總是需要權衡。 你有

  • 更頻繁的重新平衡但更短的反應時間來識別死消費者或
  • 不太頻繁的重新平衡和更長的反應時間來識別死消費者。

4. 過時的 Kerberos 票證

在我們的生產集群上,我們剛剛在應用程序無法更新 Kerberos 票證后看到 CommitFailedException。

我們遇到了類似的問題,我們通過從默認 500 減少 max.poll.records 並減少心跳間隔來解決。 如果您的消息處理需要時間並且輪詢記錄為 500,則獲得 CommitFailedException 的可能性很高。

我有類似的問題,我能夠通過將 max.poll.records 從默認的 500 減少到更小的數字(如 100-200)來解決它。 如果您的消息處理需要時間並且輪詢記錄為 500,則獲得 CommitFailedException 的可能性很高。

我正在使用 Kstream 並得到相同的異常。 我根據解決我的問題的建議增加了 max.poll.interval 時間並添加了心跳間隔。請注意,如果您的處理花費更多時間,請將 max.poll 記錄設置為 1 並進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM