Apache kafka 卡夫卡——从CLI开始与卡夫卡Java API

Apache kafka 卡夫卡——从CLI开始与卡夫卡Java API,apache-kafka,kafka-consumer-api,spring-kafka,Apache Kafka,Kafka Consumer Api,Spring Kafka,最近,在使用Kafka时,我的应用程序需要从一开始就访问主题中的所有消息。因此,在编写Kafka消费者(使用JavaAPI)时,我能够从头开始阅读消息,但它只返回主题中的前500条消息。试图增加 put(ConsumerConfig.MAX\u POLL\u RECORDS\u CONFIG,Integer.MAX\u VALUE); put(ConsumerConfig.FETCH\u MAX\u BYTES\u CONFIG,Long.MAX\u VALUE) 但它仍然不会返回所有消息,而在

最近,在使用Kafka时,我的应用程序需要从一开始就访问主题中的所有消息。因此,在编写Kafka消费者(使用JavaAPI)时,我能够从头开始阅读消息,但它只返回主题中的前500条消息。试图增加

put(ConsumerConfig.MAX\u POLL\u RECORDS\u CONFIG,Integer.MAX\u VALUE); put(ConsumerConfig.FETCH\u MAX\u BYTES\u CONFIG,Long.MAX\u VALUE)

但它仍然不会返回所有消息,而在使用CLI命令时

kafka控制台使用者--引导服务器localhost:9092--主题 --从一开始

它会返回我所有的5000条记录

伙计们,有什么配置丢失了吗? 任何帮助都是值得的

[编辑:1] 消费者代码

public ConsumerRecords Pullfrom Kafka(字符串主题名、地图道具){
卡夫卡消费者=新卡夫卡消费者(道具);
consumer.subscribe(新的ArrayList(Collections.singletonList(topicname));
消费者调查(0);
//阅读主题从头开始偏移
consumer.seektobegining(consumer.assignment());
//如果没有答复,则轮询和超时
ConsumerRecords记录=consumer.poll(1000);
consumer.close();
退货记录;
}
然而,我改变了消费者:

公共地图pullFromKafka(字符串主题名,地图道具){
卡夫卡消费者=新卡夫卡消费者(道具);
Map entityMap=newhashmap();
布尔停止=假;
consumer.subscribe(新的ArrayList(Collections.singletonList(topicname));
消费者调查(0);
//阅读主题从头开始偏移
consumer.seektobegining(consumer.assignment());
当(!停止){
//请求主题中的未读邮件。
ConsumerRecords ConsumerRecords=consumer.poll(1000);
迭代器迭代器=consumerRecords.Iterator();
if(iterator.hasNext()){
while(iterator.hasNext()){
ConsumerRecord记录=迭代器.next();
//遍历返回的记录,提取值
//并将值打印到标准输出。
entityMap.put(新字符串(record.key()),record.value());
}
}否则{
停止=真;
}
}
返回entityMap;
}

虽然现在它正在获取所有记录,但我想知道是否有更好的方法。

使用
seektobegining()
来使用所有消息没有什么错

然而,有一种更灵活的方法来实现同样的结果。您可以通过配置来实现这一点,这允许您从开始到结束都使用相同的代码。这也是
kafka console consumer.sh
工具使用的方法:

  • 设置
    auto.offset.reset
    最早

  • group.id
    设置为新的/随机值。如果您对跟踪此消费者位置不感兴趣,但始终希望从头开始,则还可以将
    enable.auto.commit
    设置为false,以避免污染补偿主题

  • 从逻辑中删除
    seektobegining()

  • 关于你的逻辑,你应该考虑以下几点:

  • 在某些情况下,
    poll()
    可以返回空集合,即使它尚未到达末尾。主题也是一个流(无界),末端可以移动。无论哪种方式,您都可以使用
    endOffsets()
    查找当前结束偏移量,并将其与返回消息的偏移量进行比较

  • 在你到达终点之前,你可能不想投票。一个主题的大小可以是几GB,并且包含数百万条记录。将所有内容存储在地图中很容易导致OutOfMemory问题


  • 您可以发布您的消费代码示例。顺便说一下,您可以查看Github上的Kafka Console消费代码,查看它是如何工作的/设置了哪些属性谢谢您的宝贵意见,我一定会检查这些。然而,我使用地图收集所有独特的记录根据id的
    public ConsumerRecords<byte[], byte[]> pullFromKafka(String topicname, Map<String, Object> props) {
        KafkaConsumer<byte[], byte[]> consumer = new KafkaConsumer<byte[], byte[]>(props);
        consumer.subscribe(new ArrayList<String>(Collections.singletonList(topicname)));
        consumer.poll(0);
        // Reading topic offset from beginning
        consumer.seekToBeginning(consumer.assignment());
        // poll and time-out if no replies
        ConsumerRecords<byte[], byte[]> records = consumer.poll(1000);
        consumer.close();
        return records;
    }
    
    public Map<String, byte[]> pullFromKafka(String topicname, Map<String, Object> props) {
        KafkaConsumer<byte[], byte[]> consumer = new KafkaConsumer<byte[], byte[]>(props);
        Map<String, byte[]> entityMap = new HashMap<String, byte[]>();
        boolean stop = false;
        consumer.subscribe(new ArrayList<String>(Collections.singletonList(topicname)));
        consumer.poll(0);
        // Reading topic offset from beginning
        consumer.seekToBeginning(consumer.assignment());
        while (!stop) {
            // Request unread messages from the topic.
            ConsumerRecords<byte[], byte[]> consumerRecords = consumer.poll(1000);
            Iterator<ConsumerRecord<byte[], byte[]>> iterator = consumerRecords.iterator();
            if (iterator.hasNext()) {
                while (iterator.hasNext()) {
                    ConsumerRecord<byte[], byte[]> record = iterator.next();
                    // Iterate through returned records, extract the value
                    // of each message, and print the value to standard output.
                    entityMap.put(new String(record.key()), record.value());
                }
            } else {
                stop = true;
            }
        }
        return entityMap;
    }