为什么我的Kafka Consumer在首次运行时会快速消耗消息,但在将来的运行中会大幅减慢消息?

时间:2015-06-15 21:48:39

标签: java apache-kafka

我是一名研究和玩卡夫卡的学生。在关注Apache文档的示例之后,我正在使用当前Github仓库的主干中的示例部分。

截至目前,该示例实现了Consumer的“较旧”版本,并未使用新的KafkaConsumer。在文档之后,我编写了自己的KafkaConsumer版本,认为它会更快。

这是一个模糊的问题,但是在问题上,我会向主题“test”生成5000条简单消息,例如“Message_CurrentMessageNumber”,然后使用我的消费者获取这些消息并将其打印到stdout。当我运行示例代码替换提供的消费者时使用较新的KafkaConsumer(v 0.8.2及更高版本)时,它的工作速度非常快,与第一个例子中的示例相当,但在此之后的任何时候都会显着减慢。

我注意到我的Kafka Server输出

  

重新平衡第1组第3组(kafka.coordinator.ConsumerCoordinator)

或类似的消息经常让我相信Kafka必须做某种负载平衡,这会减慢速度,但我想知道是否有其他人对我的错误有所了解。

public class AlternateConsumer extends Thread {

    private final KafkaConsumer<Integer, String> consumer;
    private final String topic;
    private final Boolean isAsync = false;

     public AlternateConsumer(String topic) {
        Properties properties = new Properties();
        properties.put("bootstrap.servers", "localhost:9092");
        properties.put("group.id", "newestGroup");
        properties.put("partition.assignment.strategy", "roundrobin");
        properties.put("enable.auto.commit", "true");
        properties.put("auto.commit.interval.ms", "1000");
        properties.put("session.timeout.ms", "30000");
        properties.put("key.deserializer", "org.apache.kafka.common.serialization.IntegerDeserializer");
        properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        consumer = new KafkaConsumer<Integer, String>(properties);
        consumer.subscribe(topic);
        this.topic = topic;
    }

    public void run() {
        while (true) {
            ConsumerRecords<Integer, String> records = consumer.poll(100);
            for (ConsumerRecord<Integer, String> record : records) {
                System.out.println("We received message: " + record.value() + " from topic: " + record.topic());
            }
        }

        // ConsumerRecords<Integer, String> records = consumer.poll(0);
        // for (ConsumerRecord<Integer, String> record : records) {
        //  System.out.println("We received message: " + record.value() + " from topic: " + record.topic());
        // }
        // consumer.close();
    }
} 

开始:

package kafka.examples;

public class KafkaConsumerProducerDemo implements KafkaProperties
{
  public static void main(String[] args) {
    final boolean isAsync = args.length > 0 ? !args[0].trim().toLowerCase().equals("sync") : true;

    Producer producerThread = new Producer("test", isAsync);
    producerThread.start();

    AlternateConsumer consumerThread = new AlternateConsumer("test");
    consumerThread.start();
  } 
}

生产者是位于此处的默认生产者:https://github.com/apache/kafka/blob/trunk/examples/src/main/java/kafka/examples/Producer.java

1 个答案:

答案 0 :(得分:1)

不应该是这种情况。如果您的两个消费者之间的设置类似,那么除非在客户端/消费者实现中存在问题,否则您应该期望新消费者获得更好的结果,这似乎就是这种情况。

您是否可以分享您的基准测试结果以及报告的重新平衡和/或任何模式的频率(例如,在启动后,在固定消息消耗之后,队列耗尽后等等),您正在观察。此外,如果您可以分享有关您的消费者实施的一些细节。