给出主题名称,分区号和偏移量,如何从该主题中读取一条记录?
在基于Sprng Boot的应用程序中,我使用Kafka导入业务数据。 导入记录被发送到 import_queue 并由一个或多个业务模块使用。即使使用者未能从记录中导入数据,也无法继续从以下记录中导入数据,但始终会确认记录。
稍后(在他/她修复了一些相关业务数据之后)用户可以决定重新发送一个或多个失败(但已确认)的导入记录。
每条记录的偏移量,分区号和主题名称都存储在我的应用程序内部的SQL数据库中。
从参考文档和一些StackOverflow问题中,我发现我必须:
这是从kafka主题中仅读取一个旧记录的唯一方法吗? 还是有更简单的解决方案?
如@Gary所建议:
ConsumerRecord<byte[], byte[]> read(String topic, int partition, long offset) {
Map<String, Object> configs = Map.of(
"bootstrap.servers", "localhost:9092",
"group.id", "incubator_retry",
"max.poll.records", 1);
DefaultKafkaConsumerFactory<byte[], byte[]> consumerFactory = new DefaultKafkaConsumerFactory<>(
configs, new ByteArrayDeserializer(), new ByteArrayDeserializer());
try (Consumer<byte[], byte[]> consumer = consumerFactory.createConsumer()) {
TopicPartition topicPartition = new TopicPartition(topic, partition);
consumer.assign(List.of(topicPartition));
consumer.seek(topicPartition, offset);
ConsumerRecords<byte[], byte[]> consumerRecords = consumer.poll(Duration.ofMillis(5000));
if (consumerRecords.isEmpty()) {
throw new RuntimeException(String.format("Timeout polling from topic %s partition %d at offset %d",
topicPartition.topic(), topicPartition.partition(), offset));
}
return consumerRecords.iterator().next();
}
}
答案 0 :(得分:1)
有一个更简单的解决方案。
DefaultConsumerFactory
创建一个KafkaConsumer
(或简单地创建一个)group.id
max.poll.records
属性设置为1 consumer.assign(...)
所需的主题/分区seek(...)
到所需的偏移量poll(...)
直到获得记录close()
消费者如果您正在使用任何消息转换(除了Kafka解串器),则必须手动调用该转换器。