【问题标题】:Which kafka property decides Poll frequency for KafkaConsumer?哪个 kafka 属性决定了 KafkaConsumer 的轮询频率?
【发布时间】:2019-10-11 20:00:08
【问题描述】:

我正在尝试了解有关 kafka 流(kafka 流客户端到 kafka)的一些细节。

我知道 KafkConsumer(java 客户端)会从 kafka 获取数据,但是我无法理解客户端轮询 kakfa 主题以获取数据的频率?

【问题讨论】:

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


    【解决方案1】:

    投票的频率由您的代码定义,因为您负责调用 poll。 使用 KafkaConsumer 的用户代码的一个非常幼稚的示例就像 following

    public class KafkaConsumerExample {
      ...
    
    
        static void runConsumer() throws InterruptedException {
            final Consumer<Long, String> consumer = createConsumer();
    
            final int giveUp = 100;   int noRecordsCount = 0;
    
            while (true) {
                final ConsumerRecords<Long, String> consumerRecords =
                        consumer.poll(1000);
    
                if (consumerRecords.count()==0) {
                    noRecordsCount++;
                    if (noRecordsCount > giveUp) break;
                    else continue;
                }
    
                consumerRecords.forEach(record -> {
                    System.out.printf("Consumer Record:(%d, %s, %d, %d)\n",
                            record.key(), record.value(),
                            record.partition(), record.offset());
                });
    
                consumer.commitAsync();
            }
            consumer.close();
            System.out.println("DONE");
        }
    }
    

    在这种情况下,频率由处理consumerRecords.forEach 中的消息的持续时间定义。

    但是,请记住,如果您没有“足够快”地调用 poll,您的消费者将被代理协调器视为已死亡,并且将触发重新平衡。 这个“足够快”是由 kafka >= 0.10.1.0 中的max.poll.interval.ms 属性决定的。详情请见this answer

    max.poll.interval.ms 默认值为五分钟,因此如果您的consumerRecords.forEach 花费的时间超过该时间,您的消费者将被视为死亡。

    如果您不想直接使用原始的 KafkaConsumer,您可以使用 alpakka kafka,这是一个以 安全 和背压方式(基于在 akka 流上)。
    有了这个库,轮询的频率由配置akka.kafka.consumer.poll-interval决定。
    我们说是安全的,因为它会继续轮询以避免消费者被认为已死亡,即使您的处理无法跟上速率。它能够做到这一点是因为KafkaConsumer 允许暂停消费者

     /**
         * Suspend fetching from the requested partitions. Future calls to {@link #poll(Duration)} will not return
         * any records from these partitions until they have been resumed using {@link #resume(Collection)}.
         * Note that this method does not affect partition subscription. In particular, it does not cause a group
         * rebalance when automatic assignment is used.
         * @param partitions The partitions which should be paused
         * @throws IllegalStateException if any of the provided partitions are not currently assigned to this consumer
         */
        @Override
        public void pause(Collection<TopicPartition> partitions) { ... }
    

    要完全理解这一点,您应该阅读有关 akka-streams 和背压的内容。

    【讨论】:

    • 感谢您的信息。我的印象是这会自动发生,我们不会为 polling() 做任何事情
    • 如果回答了您的问题,请标记为正确
    • 还有一个问题,当我们编写流处理器时,我们不会编写 poll(),它是 API 本身的一部分,但那里有类似的机制吗?
    • 我不知道你对流处理器到底是什么意思,但是每个基于KafkaConsumer 构建的消费者都使用这种机制。即使他们不使用KafkaConsumer,他们必须使用kafka协议,尤其是消息Fetch来获取记录。
    • 似乎这两个问题都来自@CuriousMind——请不要发布重复的问题。我建议删除这个问题,因为另一个问题已经有了合适的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多