1 Exactly Once
幂等性producer & 事务producer是保证Exactly Once的两种机制。
2 幂等性producer
2.1 什么是幂等性
幂等性producer 可以保证同一次会话同一分区的精确一次性。
2.2 如何启用
要启用幂等性,只需要对Producer的参数进行设置即可。
props.put("enable.idempotence", true)或
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)
2.3 原理
- 空间换时间,在Broker端多保存一些字段
- 当Producer发送了具有相同字段值的消息后,Broker能够自动发现这些重复消息,然后默默丢弃
2.4 作用范围
- 幂等性Producer只能保证单分区上的幂等性
- 即只能保证某个主题上的一个分区上不出现重复消息,无法实现多个分区的幂等性
- 幂等性Producer只能实现单会话上的幂等性,不能实现跨会话的幂等性
- 会话:Producer进程的一次运行,如果重启Producer进程,将丢失幂等性保证
3 事务producer
3.1
事务
- 数据库事务提供了ACID的安全性保障:Atomicity、Consistency、Isolation、Durability
- Kafka在0.11版本开始提供了对事务的支持,目前主要在Read Committed的隔离级别上做事情
保证多条消息原子性地写入目标分区,同时也保证Consumer只能看到事务成功提交的消息
事务producer
- 事务Producer能够保证一批消息原子性地写入多个分区,这批消息要么全部写入成功,要么全部写入失败
- 事务Producer允许进程重启,Producer重启后,Kafka依然保证它们发送的消息的精确一次性
3.2 如何启用
props.put("enable.idempotence", true)或
props.put("transactional.id", "my-transactional-id")
3.3 原理
为了实现这种效果,应用程序必须提供一个稳定的(重启后不变)唯一的ID,也即Transaction ID。Transactin ID与PID可能一一对应。区别在于Transaction ID由用户提供,而PID是内部的实现对用户透明。
3.4 作用范围
- 事务Producer能保证跨分区上的幂等性
- 即能保证某个主题上的不同分区上不出现重复消息,实现多个分区的幂等性。
- 事务Producer能实现跨会话的幂等性
- 会话:Producer进程的一次运行,如果重启Producer进程,不会丢失幂等性保证。
3.5 consumer的读取
record1和record2会被当作一个事务统一提交到Kafka,要么全部提交成功,要么全部写入失败
即使写入失败,Kafka也会把它们写入到底层日志
中,即Consumer还是会看到这些消息。
因此在Consumer端,读取事务Producer发送的消息,需要设置isolation.level参数
- read_uncommitted
- 默认值,Consumer能够读取到Kafka写入的
任何消息
,不论事务Producer提交事务还是终止事务。
- 默认值,Consumer能够读取到Kafka写入的
- read_committed
- Consumer只会读取到
事务Producer成功提交事务写入的消息
,也能读取到非事务Producer写入的所有消息
。
- Consumer只会读取到
4 总结
- 幂等性Producer和事务Producer都是Kafka社区为了实现
精确一次
处理语义所提供的工具,只是作用范围
不同而已。 - 幂等性Producer只能保证
单分区、单会话
上的消息幂等性;而事务Producer能够保证跨分区、跨会话
的幂等性。 - 事务Producer与幂等性Producer相比,
性能更差
。