14 | 幂等生产者和事务生产者是一回事吗?
14 | 幂等生产者和事务生产者是一回事吗?
讲述:胡夕
时长10:13大小8.18M
什么是幂等性(Idempotence)?
幂等性 Producer
事务
事务型 Producer
小结
开放讨论
赞 29
提建议
精选留言(112)
- 时隐时现2019-09-08幂等性producer和事务型producer实现原理都没有涉及,这篇有点太肤浅了共 10 条评论138
- Jowin2019-07-26研究了一下kafka的设计文档,基本搞清楚了幂等和事务消息,一些理解,https://www.jianshu.com/p/f77ade3f41fd, 欢迎大家一起交流。共 5 条评论58
- October2019-07-04我所理解的kafka事务是这样的:生产者的事务能够保证一条消息仅仅会保存在kafka的某一个分区上,不会出现在多个分区上,另外,能够保证多条消息原子性的发送到多个分区。也就是说它只保证了从producer端到broker端消息不丢失不重复。但对于consumer端,由于偏移量的提交和消息处理的顺序有前有后,依然可能导致重复消费或者消息丢失消费,如果要实现消费者消费的精确一次,还需要通过额外机制在消费端实现偏移量提交和消息消费的事务处理。不知道自己理解的对不对,希望老师指正。展开
作者回复: 嗯嗯,我觉得很有道理:)
32 - dream2019-07-04老师,请问一下,事务型 Producer 可以实现一组消息要么全部写入成功,要么全部失败,但是事务型 Producer 是具体怎么实现多分区以及多会话上的消息无重复的呢?
作者回复: 主要的机制是两阶段提交(2PC)。引入了事务协调器的组件帮助完成分布式事务
共 4 条评论25 - 风中花2019-07-04我一直认为事务,不到必须时是不用得东西,那么我想知道,胡老师实际中,你们有用到过吗,在一些什么场景下使用?老师可以简单说下吗,谢谢
作者回复: 我们没有使用。事务更多用在Kafka Streams中。如果要实现流处理中的精确一次语义,事务是不可少的。
19 - 知易2019-08-02版本0.11.0.2,设置transactional.id并开启事务后,须同时保证retries>118
- 注定非凡2019-11-01消息交付可靠性: (1)可靠性保障,常见有三种: 最多一次(at most once):消息可能会丢失,但不会被重复发送 至少一次(at least once):消息不会丢失,但可能会重复发送 精确一次(exactly once):消息不会对丢失,也不会被重复发送 (2)Kafka默认提供交付可靠性保障是至少一次 (3)Kafka消息交付可靠性保障以及精确处理一次语义通过两种机制来实现的:冥等性(Idempotence)和事务(Transaction)。 冥等性 (1)什么是幂等性(Idempotence) A:“幂等”:原是数学概念,指某些操作或函数能够被执行多次,但每次得到的结果都不变。 B:计算机领域的含义: a,在命令式编程语言(如C)中,若一个子程序是幂等的,那它必然不能修改系统状态。无论这个子程序运行多少次,与该子程序的关联的那部分系统保持不变。 b,在函数式编程语言(比如Scala或Haskell)中,很多纯函数(pure function)天然就是幂等的,他们不执行任何的side effect。 C:冥等性的优点:最大的优势是可以安全地重试任何冥等性操作,因为他们不会破坏系统状态 (2)冥等性Producer A:开启:设置props.put(“enable.idempotence”,true)或props.put(ProducerConfig.ENABLE_IDEMPOTENC_CONFIG,true)。 B:特征:开启后,Kafka自动做消息的重复去重。 C:实现思路:用空间换取时间,Broker端多保存一些字段,当Producer发送了具有相同字段值的消息后,Broker就可以知道这些消息重复,就将这些消息丢弃。 D:作用范围: (1)只能保证单分区上幂等性,无法实现多个分区的幂等性。 (2)只能实现单会话上的冥等性,当Producer重启后,这种幂等性保证就失效了。 事务 (1)事务概念: A:事务提供的安全性保障是经典的ACID。原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)。 B:kafka的事务机制可以保证多条消息原子性地写入到目标分区,同时也能保证Consumer只能看到事务成功提交的消息。 (2)事务型Producer: A:开启: 【1】设置enable.idempotence = true。 【2】设置Producer端参数transactional.id。最好为其设置一个有意义的名字。 【3】调整Producer代码,显示调用事务API。 【4】设置Consumer端参数 isolation.level 值: read_uncommitted(默认值,能够读到kafka写入的任何消息) read_committed(Consumer只会读取事务型Producer成功事务写入的消息。) B:特征: 【1】能够保证将消息原子性地写入到多个分区中。一批消息要么全部成功,要么全部失败。 【2】不惧进程重启,Producer重启回来后,kafka依然能保证发送的消息的精确一次处理。 关键事项: 1,幂等性无法实现多个分区以及多会话上的消息无重复,但事务(transaction)或依赖事务型Produce可以做到。 2,开启事务对性能影响很大,在使用时要充分考虑展开共 1 条评论12
- calljson2019-07-09文中提到了幂等性,希望能够讲解下幂等性原理,如何实现,这样大家才能明白为何幂等性无法保证:跨回话、跨分区共 2 条评论13
- 涛2019-10-06老师,kafka中的事务提交异常,broker端的数据还是会写入日志,相当于只是记录一下失败状态,在消费端通过隔离级别,来过滤掉出这部分消息,不进行消费。为什么事务异常了,还要将数据写入日志呢?直接删除掉不好吗?像DB那样。
作者回复: Kafka broker基本上还是保持append-only的日志型风格,不做删除处理
11 - Kim2020-04-09老师,有个地方很困惑,这句话“实际上即使写入失败,Kafka 也会把它们写入到底层的日志中,也就是说 Consumer 还是会看到这些消息”这是什么意思?明明写入都失败了,为什么还会写到底层的commit log中呢?那这里的写入失败是指写入磁盘失败么?麻烦老师解答一下,谢谢~~
作者回复: 这里的写入失败是指事务失败,可能没有说太清楚。如果事务失败中止了,Kafka没法向数据库那样执行回滚,写入的日志也只能继续“躺在”日志中了,但是Kafka依赖于LSO等机制来设定一个事务型Consumer的可见范围,保证事务的准确性
共 2 条评论10 - 冉冉2020-04-23想问下老师一个关于消费者的问题,如果一个消费者组里有两个消费者c1,c2,一个topic有两个分区p1,p2,那c1永远从p1收消息,而不会收到生产者发到p2的消息对吗?
作者回复: hmmm.... 应该这么来说:从Kafka设计的角度,不是永远的关系,c1理论上可以收到p2的消息,只要发生了rebalance。但实际使用过程中,一旦你的group确定了分配策略,其实这种分配关系也就是确定的了。特别是对于你这个场景,无论发生多少次rebalance,p1应该都会被分配给c1。当然我说的是c1,c2都运行的情况下,如果c2挂了,c1肯定能收到p2的消息
9 - 妥协2020-02-23不启用幂等也可以保证同分区下无消息乱序的。——消息发送失败重发时,在broker端不会导致收到的顺序,和producer端发送顺序不一致吗?如果是的话,是类似TCP那种保证有序的机制吗?
作者回复: 需要配合参数max.in.flight.requests.per.connection = 1来实现。这样producer会等待之前请求的消息发送成功才会发送下一个,从而不会乱序
7 - 南山2019-11-09老师,事务型producer不会重复发送消息吗?如果发送的这一批到broker了,但是broker返回的确认消息producer没有收到,再次尝试,broker会去重吗?或者consumer端会去重啊?
作者回复: producer端可能发送重复消息,broker端有一套机制来去重(幂等性依赖seq number机制,事务依赖各种marker来标记)
7 - Liam2019-07-04retry的话producer会保证发送到同一个分区吧,不然幂等性就没法保证了
作者回复: 是的,会保证
6 - 妥协2020-03-12重启之后标识producer的PID就变化了,broker就不认识了——这个是幂等性的另一个限制条件,无法实现夸会话的幂等性。我理解的是:一个幂等性的producer,只保证单分区的幂等性,而producer的消息会发给一个主题的多个分区,每个单分区都保证幂等性,其实就是实现了多分区的幂等性,只是无法实现跨会话的幂等性,不知道理解的对不对?
作者回复: 嗯,很有道理:)
共 4 条评论5 - 快跑2019-07-05老师,你好 幂等性为什么只保证单分区有效?是因为下一次消息重试指不定发送到哪个分区么。如果这样的话是不是可以采用按消息键保序的方式?这样重试消息还发送到同一个分区。
作者回复: 重启之后标识producer的PID就变化了,broker就不认识了。要想认识就要让broker和producer做更多的事,也就是事务机制做的那些事。 重试还是发送到同一个分区
共 2 条评论5 - 奇奇2019-08-28事务还有用 冥等生产者没什么用,反正消费端都是有可能重复消费的,业务上必须做去重处理
作者回复: Kafka Streams依靠幂等producer和事务机制来保证EOS
共 2 条评论4 - 明翼2019-07-05老师请教个问题啊,我们在一个生产环境是日志入kafka,然后读取kafka的数据入到es里面,由于数据比较多,所以入到kafka的数据可能要过半天到一天才可以处理完,结果发现一个很奇怪的现象就是kafka的入的数据越快,那么入es的速度也越快,本来怀疑是kafka数据在cache里面所以快的,但是我们的数据延迟了很久,不太可能在cache,而且通过读kafka的程序日志分析,读kafka环节一直很快,只是入es的时间有快又慢,这个可能是什么问题那?展开
作者回复: 如果consumer能够读取page cache中的数据而不是要去磁盘执行物理读,那么可以用上zero copy,速度应该是很快的。你可以看下你的consumer消费时broker的物理读IO,如果很低,大概率走的是page cache。另外如果读kafka很快,es忽高忽低,那是不是应该查一下ES的写入?
共 2 条评论4 - Geek_rebecca2020-06-08老师,kafka的幂等性仅限于单分区会话,producer重启PID会变。那是不是说明其实kafka还是不能保证不会重复消费消息,如果要做到不重复消费,只能consumer端的代码逻辑里面去重过滤。
作者回复: 不能完全避免消费者重复消费。最好还是使用业务去重
3 - 胡小禾2020-05-12即使consumer读到了事务消息,但还是可能由于rebalance等原因导致重复消费的吧?
作者回复: 嗯, 是的~
共 2 条评论2