幂等机制
入门
对于某些比较重要的消息,我们需要保证exactly once语义,即保证每条消息被发送且仅被发送一次。
在0.11版本之后,Kafka引入了幂等性机制(idempotent),配合acks = -1时的at least once(最少一次)语义,实现了producer到broker的exactly once语义。
***\*idempotent + at least once = exactly once\****
使用时,只需将enable.idempotence属性设置为true(在生产者的位置),kafka自动将acks属性设为-1。
ps:幂等性机制是什么意思,幂等简单说1的几次幂都等于1,也就是说一条消息无论发几次都只算一次,无论多少条消息但只实例化一次
目的
为了保证producer在重试发送消息时出现重复的数据保存在消息队列中,引入 幂等机制.
什么情况下可能导致数据重复发送
OOM,网络,FullGC等等,都有可能导致producer重复发送.
当生产者没有收到broker的确认信息时,会认为发送失败.会再次发送,此时需要一种机制保证数据不会被重复发送,
kafaka如何实现幂等性?(去掉重复数据)
ProducerId:每一个生产者的唯一ID,对于客户端不可见
SequenceNumber:每个生产者,每个Topic及分区对应一个唯一单调递增值.
发送消息的时候带上ProducerId
和SequenceNumber
,相同的消息SequenceNumber
时一样的,发送时不会被接受.
那么,幂等是如何实现的呢?由于消息是分batch(批次)
发送的,每个batch
都有一个序列号。在Broker
端,会追踪每个分区的最大序列号
。如果出现序列号较小或相等的batch(批次)
,broker
将不会将该batch
写入topic
。这样,除了保证了幂等性,还可以确保batch的顺序。
如何开启幂等机制?
实现不关心,怎么用? ,配置里改个参数就行
object kafakaTest2 extends App {
private val prop = new Properties()
prop.load(kafakaTest2.getClass.getClassLoader.getResourceAsStream("producer.properties"))
//启用幂等机制
prop.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true")
//获取生产者对象
private val producer = new KafkaProducer[Integer, String](prop)
//获取记录
private val message = new ProducerRecord[Integer, String]("pet", "you are rich")
producer.send(message)
producer.close()
}
注意事项
1.配置文件中的acks必须=all,否则会报错
Caused by: org.apache.kafka.common.config.ConfigException: Must set acks to all in order to use the idempotent producer. Otherwise we cannot guarantee idempotence.
at org.apache.kafka.clients.producer.KafkaProducer.configureAcks(KafkaProducer.java:533)