Kafka CommitFailedException消费者异常

时间:2016-02-26 17:34:30

标签: java apache-kafka kafka-consumer-api

创建多个使用者(使用Kafka 0.9 java API)并启动每个线程后,我收到以下异常

Consumer has failed with exception: org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed due to group rebalance
class com.messagehub.consumer.Consumer is shutting down.
org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed due to group rebalance
at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$OffsetCommitResponseHandler.handle(ConsumerCoordinator.java:546)
at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$OffsetCommitResponseHandler.handle(ConsumerCoordinator.java:487)
at org.apache.kafka.clients.consumer.internals.AbstractCoordinator$CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:681)
at org.apache.kafka.clients.consumer.internals.AbstractCoordinator$CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:654)
at org.apache.kafka.clients.consumer.internals.RequestFuture$1.onSuccess(RequestFuture.java:167)
at org.apache.kafka.clients.consumer.internals.RequestFuture.fireSuccess(RequestFuture.java:133)
at org.apache.kafka.clients.consumer.internals.RequestFuture.complete(RequestFuture.java:107)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient$RequestFutureCompletionHandler.onComplete(ConsumerNetworkClient.java:350)
at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:288)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.clientPoll(ConsumerNetworkClient.java:303)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:197)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:187)
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:157)
at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.commitOffsetsSync(ConsumerCoordinator.java:352)
at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:936)
at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:905)

然后开始正常消费消息,我想知道导致此异常的原因是为了解决它。

3 个答案:

答案 0 :(得分:12)

还要尝试调整以下参数:

  • heartbeat.interval.ms - 这告诉Kafka在考虑消费者将被考虑之前等待指定的毫秒数"死"
  • max.partition.fetch.bytes - 这将限制消费者在轮询时将收到的消息量(最多)。

我注意到,如果消费者在心跳超时之前没有提交Kafka,则会发生重新平衡。如果在处理消息后发生提交,则处理它们的时间将决定这些参数。因此,减少消息数量和增加心跳时间将有助于避免重新平衡。

还考虑使用更多分区,因此处理数据的线程会更多,即使每次轮询的消息更少。

我写了这个小应用程序来进行测试。希望它有所帮助。

https://github.com/ajkret/kafka-sample

<强>更新

Kafka 0.10.x现在提供了一个新参数来控制收到的消息数量:   - max.poll.records - 一次调用poll()时返回的最大记录数。

<强>更新

Kafka提供了一种暂停队列的方法。当队列暂停时,您可以在单独的线程中处理消息,允许您调用 KafkaConsumer.poll()来发送心跳。然后在处理完成后调用 KafkaConsumer.resume()。这样可以缓解由于未发送心跳而导致导致重新平衡的问题。以下是您可以做的事情的概述:

while(true) {
    ConsumerRecords records = consumer.poll(Integer.MAX_VALUE);
    consumer.commitSync();

    consumer.pause();
    for(ConsumerRecord record: records) {

        Future<Boolean> future = workers.submit(() -> {
            // Process
            return true;
        }); 


       while (true) {
            try {
                if (future.get(1, TimeUnit.SECONDS) != null) {
                    break;
                }
            } catch (java.util.concurrent.TimeoutException e) {
                getConsumer().poll(0);
            }
        }
    }

    consumer.resume();
}

答案 1 :(得分:0)

两个可能的原因 -->

  1. 如果出现任何网络故障,消费者将无法联系到代理并将抛出此异常。但是发生这些异常时并没有出现网络故障。
  2. 如错误跟踪中所述,如果处理消息花费了太多时间,ConsumerCoordinator 将失去连接并且提交将失败。这是因为投票。

此处给出的值是默认的 Kafka 消费者配置值。

request.timeout.ms=40000
heartbeat.interval.ms=3000
max.poll.interval.ms=300000
max.poll.records=500
session.timeout.ms=10000

解决方案-->

将 max.poll.records 减少到 100 但仍然,异常发生了几次。于是修改如下配置;

request.timeout.ms=300000
heartbeat.interval.ms=1000 
max.poll.interval.ms=900000
max.poll.records=100
session.timeout.ms=600000

减少心跳间隔,以便代理会经常更新消费者处于活动状态。并且还增加了会话超时配置。

答案 2 :(得分:-1)

正如错误所说,其消费者群体重新平衡问题。你能告诉我们,创建了多少分区主题?有多少消费者在运营?他们属于同一群体吗?