我们希望使用exactly-once语义将数据存储在Kafka中,以避免消息重复。具有以下属性的生成器:
spring.kafka.producer.properties.acks=all
spring.kafka.producer.properties.enable.idempotence=trueKafka主题描述:
Topic: topicName PartitionCount: 1 ReplicationFactor: 1
Configs: Topic: topicName Partition: 0 Leader: 1 Replicas: 1 Isr: 1集成测试:
@Test
void exactlyOnceTest() {
kafkaTemplate.send("topicName", "key", "data");
kafkaTemplate.send("topicName", "key", "data");
kafkaTemplate.send("topicName", "key", "data");
}我们的期望是只有一条消息应该存储在Kafka中,但实际结果是3条消息。
我怎样才能使用Kafka来做一次激动人心的语义呢?
我的配置中缺少什么?
发布于 2021-07-27 17:49:58
只有一次语义不会以这种方式工作,
当生产者在过程中失败时,幂等生产者被配置为避免重复或无序的行,
考虑以下场景:您向topic发送消息,您的生产者客户端正在等待broker的确认,消息已写入kafka,但现在存在网络错误,并且确认从未收到到producer客户端,您的生产者将进行内部重试以生成消息,该消息将被再次发送到broker。
如果您没有启用idemptance,那么您的代理将再次写入消息并向您发送确认,您将在主题中获得重复的消息。
如果您启用了idemptance,broker将理解这是生产者的重试,消息已经写入topic,他只会向您发送确认,主题中没有重复。
在你的测试中,你只产生了3条相同值的消息,它们是不同的“线程”……因此,您最终将在该主题中有3条消息
对于您的信息,apache kafka项目正在非常密集地检查他们添加的所有内容,以避免任何破坏性的更改,它非常稳定,您可以通过此链接查看他们是如何测试idemptance生成器功能的。
https://stackoverflow.com/questions/68542265
复制相似问题