Kafka 幂等性 设置

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

幂等性最大的优势在于我们可以安全地重试任何幂等性操作,反正它们也不会破坏我们的系统状态。

在 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幂等性特性通过引入唯一标识符(PID)和序列号机制,确保生产者在发送消息时,即使发生重试,也不会导致消息重复。每个生产者实例都会被分配一个唯一的 PID,而每条发送的消息都会携带一个递增的序列号,用于标识该消息在发送顺序中的位置。Broker 会为每个 `<PID, 分区>` 组合维护一个序列号窗口,记录最近收到的序列号。当收到一条消息的序列号小于或等于当前记录值时,Broker 会判断该消息为重复发送,并直接丢弃它,同时返回成功确认给生产者(模拟写入成功)[^5]。 这种机制确保了即使在网络不稳定或发生故障的情况下,Kafka 仍然能够避免消息重复的问题。例如,在模拟网络故障的测试方案中,当生产者发送消息并触发重试后,消费者最终只会收到一条消息,验证了幂等性机制的有效性 [^4]。 ### 配置与使用 Kafka幂等性功能是在 0.11.0.0 版本中引入的,生产者默认不是幂等性的,但可以通过配置启用。启用幂等性的生产者配置如下: ```java Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("acks", "all"); props.put("retries", 0); props.put("enable.idempotence", true); // 启用幂等性 props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); Producer<String, String> producer = new KafkaProducer<>(props); ``` 通过上述配置Kafka 生产者将启用幂等性支持,从而确保消息的精确一次交付 [^1]。 ### 适用场景 Kafka幂等性适用于简单的消息发送场景,其中只需要确保消息不会重复。然而,对于需要跨分区、跨会话的原子性操作的复杂场景,则应考虑使用事务特性。幂等性与事务特性之间的选择需要在可靠性和性能之间做出权衡,选择最适合业务场景的配置 [^1]。 ### 相关问题 1. Kafka幂等性如何解决消息重复问题? 2. 如何在 Kafka 中启用幂等性? 3. Kafka幂等性与事务特性有何区别? 4. Kafka 幂等性对性能的影响有多大? 5. Kafka 幂等性在哪些场景下最有效?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值