Kafka 核心技术与实战
胡夕
Apache Kafka Committer,老虎证券技术总监
52815 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
结束语 (1讲)
Kafka 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

14 | 幂等生产者和事务生产者是一回事吗?

作用范围
作用范围
事务型Producer
ACID
幂等性Producer
幂等性的含义
精确一次
至少一次
最多一次
开放讨论
性能评估
事务
幂等性(Idempotence)
消息交付可靠性保障
Kafka消息交付可靠性保障以及精确处理一次语义的实现

该思维导图由 AI 生成,仅供参考

你好,我是胡夕。今天我要和你分享的主题是:Kafka 消息交付可靠性保障以及精确处理一次语义的实现。
所谓的消息交付可靠性保障,是指 Kafka 对 Producer 和 Consumer 要处理的消息提供什么样的承诺。常见的承诺有以下三种:
最多一次(at most once):消息可能会丢失,但绝不会被重复发送。
至少一次(at least once):消息不会丢失,但有可能被重复发送。
精确一次(exactly once):消息不会丢失,也不会被重复发送。
目前,Kafka 默认提供的交付可靠性保障是第二种,即至少一次。在专栏第 11 期中,我们说过消息“已提交”的含义,即只有 Broker 成功“提交”消息且 Producer 接到 Broker 的应答才会认为该消息成功发送。不过倘若消息成功“提交”,但 Broker 的应答没有成功发送回 Producer 端(比如网络出现瞬时抖动),那么 Producer 就无法确定消息是否真的提交成功了。因此,它只能选择重试,也就是再次发送相同的消息。这就是 Kafka 默认提供至少一次可靠性保障的原因,不过这会导致消息重复发送。
Kafka 也可以提供最多一次交付保障,只需要让 Producer 禁止重试即可。这样一来,消息要么写入成功,要么写入失败,但绝不会重复发送。我们通常不会希望出现消息丢失的情况,但一些场景里偶发的消息丢失其实是被允许的,相反,消息重复是绝对要避免的。此时,使用最多一次交付保障就是最恰当的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka消息交付可靠性保障及精确处理一次语义的实现是本文的主题。文章首先介绍了Kafka的消息交付可靠性保障的三种承诺:最多一次、至少一次和精确一次。随后详细讨论了幂等性和事务这两种机制在实现精确一次消息交付方面的作用。幂等性Producer保证消息不重复发送,但仅限于单分区和单会话;而事务型Producer实现了多分区和多会话上的消息无重复发送,同时保证消息的原子性写入。通过幂等性和事务这两种机制,Kafka实现了精确一次的消息交付语义,确保消息不会丢失,也不会被重复发送。总的来说,幂等性Producer和事务型Producer是Kafka社区为实现精确一次处理语义提供的工具,只是它们的作用范围不同。事务型Producer能够保证跨分区、跨会话间的幂等性,但性能较差,在实际使用中需要仔细评估引入事务的开销。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(113)

  • 最新
  • 精选
  • October
    我所理解的kafka事务是这样的:生产者的事务能够保证一条消息仅仅会保存在kafka的某一个分区上,不会出现在多个分区上,另外,能够保证多条消息原子性的发送到多个分区。也就是说它只保证了从producer端到broker端消息不丢失不重复。但对于consumer端,由于偏移量的提交和消息处理的顺序有前有后,依然可能导致重复消费或者消息丢失消费,如果要实现消费者消费的精确一次,还需要通过额外机制在消费端实现偏移量提交和消息消费的事务处理。不知道自己理解的对不对,希望老师指正。

    作者回复: 嗯嗯,我觉得很有道理:)

    2019-07-04
    2
    35
  • dream
    老师,请问一下,事务型 Producer 可以实现一组消息要么全部写入成功,要么全部失败,但是事务型 Producer 是具体怎么实现多分区以及多会话上的消息无重复的呢?

    作者回复: 主要的机制是两阶段提交(2PC)。引入了事务协调器的组件帮助完成分布式事务

    2019-07-04
    4
    28
  • 风中花
    我一直认为事务,不到必须时是不用得东西,那么我想知道,胡老师实际中,你们有用到过吗,在一些什么场景下使用?老师可以简单说下吗,谢谢

    作者回复: 我们没有使用。事务更多用在Kafka Streams中。如果要实现流处理中的精确一次语义,事务是不可少的。

    2019-07-04
    23
  • 老师,kafka中的事务提交异常,broker端的数据还是会写入日志,相当于只是记录一下失败状态,在消费端通过隔离级别,来过滤掉出这部分消息,不进行消费。为什么事务异常了,还要将数据写入日志呢?直接删除掉不好吗?像DB那样。

    作者回复: Kafka broker基本上还是保持append-only的日志型风格,不做删除处理

    2019-10-06
    16
  • Kim
    老师,有个地方很困惑,这句话“实际上即使写入失败,Kafka 也会把它们写入到底层的日志中,也就是说 Consumer 还是会看到这些消息”这是什么意思?明明写入都失败了,为什么还会写到底层的commit log中呢?那这里的写入失败是指写入磁盘失败么?麻烦老师解答一下,谢谢~~

    作者回复: 这里的写入失败是指事务失败,可能没有说太清楚。如果事务失败中止了,Kafka没法向数据库那样执行回滚,写入的日志也只能继续“躺在”日志中了,但是Kafka依赖于LSO等机制来设定一个事务型Consumer的可见范围,保证事务的准确性

    2020-04-09
    2
    11
  • 冉冉
    想问下老师一个关于消费者的问题,如果一个消费者组里有两个消费者c1,c2,一个topic有两个分区p1,p2,那c1永远从p1收消息,而不会收到生产者发到p2的消息对吗?

    作者回复: hmmm.... 应该这么来说:从Kafka设计的角度,不是永远的关系,c1理论上可以收到p2的消息,只要发生了rebalance。但实际使用过程中,一旦你的group确定了分配策略,其实这种分配关系也就是确定的了。特别是对于你这个场景,无论发生多少次rebalance,p1应该都会被分配给c1。当然我说的是c1,c2都运行的情况下,如果c2挂了,c1肯定能收到p2的消息

    2020-04-23
    10
  • 妥协
    不启用幂等也可以保证同分区下无消息乱序的。——消息发送失败重发时,在broker端不会导致收到的顺序,和producer端发送顺序不一致吗?如果是的话,是类似TCP那种保证有序的机制吗?

    作者回复: 需要配合参数max.in.flight.requests.per.connection = 1来实现。这样producer会等待之前请求的消息发送成功才会发送下一个,从而不会乱序

    2020-02-23
    10
  • 南山
    老师,事务型producer不会重复发送消息吗?如果发送的这一批到broker了,但是broker返回的确认消息producer没有收到,再次尝试,broker会去重吗?或者consumer端会去重啊?

    作者回复: producer端可能发送重复消息,broker端有一套机制来去重(幂等性依赖seq number机制,事务依赖各种marker来标记)

    2019-11-09
    9
  • Liam
    retry的话producer会保证发送到同一个分区吧,不然幂等性就没法保证了

    作者回复: 是的,会保证

    2019-07-04
    7
  • 妥协
    重启之后标识producer的PID就变化了,broker就不认识了——这个是幂等性的另一个限制条件,无法实现夸会话的幂等性。我理解的是:一个幂等性的producer,只保证单分区的幂等性,而producer的消息会发给一个主题的多个分区,每个单分区都保证幂等性,其实就是实现了多分区的幂等性,只是无法实现跨会话的幂等性,不知道理解的对不对?

    作者回复: 嗯,很有道理:)

    2020-03-12
    3
    5
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部