为什么“多卡夫卡消费对象”使它总是重新平衡而不起作用

时间:2018-07-08 11:10:20

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

过去,我做出了错误的决定,那就是在一个线程中操作多个使用者(相同的组ID),但是当时没有相应的使用情况,所以这个问题没有被发现。

现在,我意识到当我有多个使用者时,我的程序会出错,查询相应的信息,再加上自己的测试,我得到了这三种情况。

  1. 在一个线程中,具有相同组ID的多个使用者无法正常工作。
  2. 在一个线程中,具有不同组ID的多个使用者可以正常工作。
  3. 使用单个cpu运行2的程序,它可以正常工作。

我想我知道如何更改它,但是我不知道为什么,卡夫卡消费者在线程中存储什么样的东西会导致这种情况。

我的代码就是这样

Properties properties = new Properties();
    properties.setProperty(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, "3000");
    properties.setProperty(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "30000");
    properties.setProperty(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, "30000");
    properties.setProperty(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "500");
    properties.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
    properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "shoothzj.group");
    properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
    properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
    return properties;



private Map<String, KafkaConsumer<String, T>> consumerMap = new HashMap<>();


for (KafkaConsumer<String, T> consumer :consumerMap.values()) {
                    consumer.poll(1000);
//handle it
                }

1 个答案:

答案 0 :(得分:1)

在同一线程中不能有多个使用者具有相同的组ID。以下是Kafka: The Definitive Guide

书的摘录
  

您不能同时有多个属于同一组的消费者   线程,您不能让多个线程安全地使用同一线程   消费者。每个线程一个使用者是规则。运行多个   同一应用程序中同一组中的使用者,您将需要运行   每个都有自己的线程。将使用者逻辑包装在   自己的对象,然后使用Java的ExecutorService启动多个对象   每个线程都有自己的使用者。合流博客有一个   教程展示了如何做到这一点。

我们在其中一项设计中遇到了类似的问题,并且以艰难的方式学习了我们的课程。如果我正确地记住了根本原因,那就是这样的。假设在同一线程中有两个使用者。如果第一次轮询之后的处理花费了很长的时间,则第二个使用者可能无法将心跳发送到 groupcoordinator ,因为心跳的发送发生在 poll( )方法,这将触发重新平衡,这将导致类似死锁的情况。因此,您的两个消费者都将陷入困境,等待重新平衡完成。