文章目录

  • 消息交付可靠性保障承诺
  • 幂等性
  • Producer幂等性的方法
  • 幂等性的范围
  • 事务
  • 事务型 Producer 的方法


消息交付可靠性保障承诺

  • 最多一次:消息可能丢失,但不会重复发送
  • 至少一次:消息不会丢失,但有可能被重复发送
  • 精确一次:消息不会丢失,也不会重复发送

Kafka承诺

  • 至少一次:是Kafka默认的交付可靠性保障,当Producer出现网络抖动的时候,那么只能选择重试去发送相同的消息,这是Kafka默认的至少一次的可靠性保障。
  • 最多一次:关掉Kafka的重试即可。
  • 精确一次:需要幂等性和事务。

幂等性

幂等性可以让我们安全地重试任何幂等性操作,不会破坏系统状态。

Producer幂等性的方法
//第一种方式
props.put(“enable.idempotence”, ture)
//第二种方式
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。

Kafka 自动帮你做消息的重复去重。
在 Broker 端多保存一些字段,当 Producer 发送了具有相同字段值的消息后,Broker 能够自动知晓这些消息已经重复了,于是可以在后台默默地把它们“丢弃”掉。

幂等性的范围
  • 只能保证单分区上的幂等性
  • 只能保证单会话上的幂等性

事务

为了实现多分区、多会话上的消息无重复,引入了事务。

事务有经典的ACID特性。

Kafka 目前主要是在 read committed 隔离级别上保证多条消息原子性地写入到目标分区,同时也能保证 Consumer 只能看到事务成功提交的消息。

事务型 Producer 的方法
  • 和幂等性 Producer 一样,开启 enable.idempotence = true。
  • 设置 Producer 端参数 transctional. id。最好为其设置一个有意义的名字。

代码如下:

roducer.initTransactions();
try {
            producer.beginTransaction();
            producer.send(record1);
            producer.send(record2);
            producer.commitTransaction();
} catch (KafkaException e) {
            producer.abortTransaction();
}
  • 事务型 Producer 的显著特点是调用了一些事务 API,如initTransaction、beginTransaction、commitTransaction 和 abortTransaction,它们分别对应事务的初始化、事务开始、事务提交以及事务终止。
  • 这段代码能够保证 Record1 和 Record2 被当作一个事务统一提交到 Kafka,要么它们全部提交成功,要么全部写入失败。实际上即使写入失败,Kafka 也会把它们写入到底层的日志中,也就是说 Consumer 还是会看到这些消息。因此在 Consumer 端,读取事务型 Producer 发送的消息也是需要一些变更的。修改起来也很简单,设置 isolation.level 参数的值即可。当前这个参数有两个取值:
  • read_uncommitted:这是默认值,表明 Consumer 能够读取到 Kafka 写入的任何消息,不论事务型 Producer 提交事务还是终止事务,其写入的消息都可以读取。很显然,如果你用了事务型 Producer,那么对应的 Consumer 就不要使用这个值。
  • read_committed:表明 Consumer 只会读取事务型 Producer 成功提交事务写入的消息。当然了,它也能看到非事务型 Producer 写入的所有消息。

简单来说,幂等性 Producer 和事务型 Producer 都是 Kafka 社区力图为 Kafka 实现精确一次处理语义所提供的工具,只是它们的作用范围是不同的。幂等性 Producer 只能保证单分区、单会话上的消息幂等性;而事务能够保证跨分区、跨会话间的幂等性。从交付语义上来看,自然是事务型 Producer 能做的更多。