Kafka的消息交付可靠性保障
消息交付可靠性保障,是指 Kafka 对 Producer 和 Consumer 要处理的消息提供什么样的承诺。常见的承诺有以下三种:
- 最多一次(at most once):消息可能会丢失,但绝不会被重复发送。
- 至少一次(at least once):消息不会丢失,但有可能被重复发送。
- 精确一次(exactly once):消息不会丢失,也不会被重复发送。
Kafka用的是至少一次,即producer向broker发送消息时,必须得到broker确认才算提交成功,否则会重试,就导致重复发送。
Kafka 也可以提供最多一次交付保障,只需要让 Producer 禁止重试即可,但会有可能丢失消息。
当然精确一次是最好的,Kafka是通过幂等性(Idempotence)和事务(Transaction)保证。
一、幂等性(Idempotence)
Producer 默认不是幂等性的,0.11.0.0 版本引入的新功能,可以创建幂等性 Producer。而且只能保证单分区上的幂等性。只能实现单会话上的幂等性,不能实现跨会话的幂等性(即重启了 Producer 进程之后,这种幂等性保证就丧失了)。
在创建Producer实例时,props加上配置即可, props.put(“enable.idempotence”, ture),或 props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。
原理大致是用空间去换时间的优化思路,即在 Broker 端对Partition多保存一些字段。当 Producer 发送了具有相同字段值的消息后,Broker 能够自动知晓这些消息已经重复了,于是可以在后台默默地把它们“丢弃”掉。
想实现多分区以及多会话上的消息无重复就要依靠事务性。
二、事务性
主要是在 read committed 隔离级别上做事情。能保证多条消息原子性地写入到目标分区,同时也能保证 Consumer 只能看到事务成功提交的消息。
事务型 Producer 能够保证将消息原子性地写入到多个分区中。这批消息要么全部写入成功,要么全部失败,重启后也一样能生效。
开启方式:
1.开启 enable.idempotence = true
2.设置 Producer 端参数 transctional. id,最好是有意义的名字
3.Producer启动代码修改
多了一些事务 API,如 initTransaction、beginTransaction、commitTransaction 和 abortTransaction,它们分别对应事务的初始化、事务开始、事务提交以及事务终止。
producer.initTransactions(); try { producer.beginTransaction(); producer.send(record1); producer.send(record2); producer.commitTransaction(); } catch (KafkaException e) { producer.abortTransaction(); }
这样可以保证要么全部提交成功,要么全部写入失败。实际上即使写入失败,Kafka 也会把数据写入到底层的日志中,也就是说 Consumer 还是会看到这些消息。
因此在 Consumer 端,读取事务型 Producer 发送的消息,需要设置 isolation.level 参数的值。
- read_uncommitted:这是默认值,表明 Consumer 能够读取到 Kafka 写入的任何消息,不论事务型 Producer 提交事务还是终止事务,其写入的消息都可以读取。很显然,如果用了事务型 Producer,那么对应的 Consumer 就不要使用这个值。
- read_committed:表明 Consumer 只会读取事务型 Producer 成功提交事务写入的消息。当然了,它也能看到非事务型 Producer 写入的所有消息。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具