幂等性最大的优势在于我们可以安全地重试任何幂等性操作,反正它们也不会破坏我们的系统状态。
在 Kafka 中,Producer 默认不是幂等性的,但我们可以创建幂等性 Producer。它其实是 0.11.0.0 版本引入的新功能。指定 Producer 幂等性的方法很简单,仅需要设置一个参数即可,即
Kafka 为了实现幂等性,它在底层设计架构中引入了 ProducerID 和 SequenceNumber。
Producer 需要做的只有两件事:
1)初始化时像向 Broker 申请一个 ProducerID
2)为每条消息绑定一个 SequenceNumber
Kafka Broker 收到消息后会以 ProducerID 为单位存储 SequenceNumber,也就是说即时 Producer 重复发送了, Broker 端也会将其过滤掉。
幂等性 Producer
sarama 中使用幂等性 Producer 设置
Producer 完整代码如下:
func Producer(limit int) {
config := sarama.NewConfig()
config.Producer.Return.Successes = true
config.Producer.Return.Errors = true
config.Producer.Idempotent = true //开启幂等性
config.Producer.RequiredAcks = sarama.WaitForAll // 开启幂等性后 acks 必须设置为 -1
config.Net.MaxOpenRequests = 1 // 并发请求数也只能为1
producer, err := sarama.NewSyncProducer([]string{conf.HOST}, config)
if err != nil {
log.Fatal("NewSyncProducer err:", err)
}
defer producer.Close()
var success, errors int
for i := 0; i < limit; i++ {
str := "生产第" + strconv.Itoa(i) + "条消息"
msg := &sarama.ProducerMessage{
Topic: conf.TOPIC,
Key: nil,
Value: sarama.StringEncoder(str)}
partition, offset, err := producer.SendMessage(msg)
if err != nil {
log.Printf("SendMessage:%d err:%v\n ", i, err)
errors++
continue
}
success++
log.Printf("[Producer] partitionid: %d; offset:%d, value: %s\n", partition, offset, str)
}
log.Printf("发送完毕 总发送条数:%d successes: %d errors: %d\n", limit, success, errors)
}
源码简单分析

在这个newAsyncProducer中一个方法

这个newTransactionManager创建一个TransactionManager,这个就是用于保证 幂等性的。newTransactionManager的源码如下

这个方法会返回一个事务。
本文介绍了Kafka中幂等性Producer。幂等性操作可安全重试,Kafka的Producer默认非幂等,0.11.0.0版本引入幂等性功能,指定幂等性只需设置一个参数。Kafka通过引入ProducerID和SequenceNumber实现幂等,还提及了sarama中使用幂等性Producer的设置及源码简单分析。
1281

被折叠的 条评论
为什么被折叠?



