如何在一个S3 PutObject事务中存储具有分区偏移量的kafka消息数据以实现Exactly Once语义?有可能吗?
答案 0 :(得分:0)
是的,应该是可能的。一种方法是控制偏移管理。
您的消费者可以随时从Kafka读取一条消息并将其作为AWS中的对象,同时将该商店偏移+分区名称作为AWS中的密钥。现在让我们说你的客户崩溃了。当下次查询S3时,查找S3中的最后一个偏移量并从那里开始读取消息。在将消息放入S3之前,为了获得额外的保护,请检查具有该密钥的对象(如果您的生产者为消息生成UUID并且您可以使用它,那将更好),如果是,则不存在,不要覆盖它,而是跳过消息。
kafkaConsumer.subscribe(Arrays.asList(topicName), new ConsumerRebalanceListener() {
public void onPartitionsRevoked(Collection<TopicPartition> partitions) {}
public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
Iterator<TopicPartition> topicPartitionIterator = partitions.iterator();
while(topicPartitionIterator.hasNext()){
TopicPartition topicPartition = topicPartitionIterator.next();
System.out.println("Current offset is " + kafkaConsumer.position(topicPartition) + " committed offset is kafkaConsumer.committed(topicPartition)
System.out.println("Resetting offset to " + startingOffset);
kafkaConsumer.seek(topicPartition, startingOffset);
}
}
}
});
希望有所帮助