Kafka 幂等生产者和事务生产者特性(讨论基于 kafka-python | confluent-kafka 客户端)
Kafka 提供了一个消息交付可靠性保障以及精确处理一次语义的实现。通常来说消息队列都提供多种消息语义保证
最多一次 (at most once): 消息可能会丢失,但绝不会被重复发送。
至少一次 (at least once): 消息不会丢失,但有可能被重复发送。
精确一次 (exactly once): 消息不会丢失,也不会被重复发送。
默认情况下社区维护的 python-kafka 包会使用 ack1 但是 retry 0 的设置,也就是说 python-kafka 不会对发送失败的消息进行重试。如果 partition leader 写入成功了就认为成功了。在极端情况下 leader 写入成功但是复制失败了,可能会导致消息丢失。但是这里如果发送都未经 leader 确认,那么程序会失败。如果没有重试会交给代码进行自动重试 如果有 retry 会自己重试来保证消息不丢失。还有一种情况时候 producer 发了 broker 也写成功了 在 broker 返回消息的时候消息没有到达,producer 又配置了重试,那么会进行重试,那么消息就重复了。
根据上述情况,所以 kafka-python 客户端设置的是至少一次的语义。
如果设置为 ack 为 0 ,那么实现的是 最多一次语义。
那么如何设置精确一次语义呢?
幂等 Producer
Kafka 提供了幂等生产者和事务生产特性来实现精确一次的语义。(很可惜截止到写文的今天,由社区维护的 kafka-python 也还没有实现幂等生产者和事务功能,但是 confluent 公司的 python 客户端已经在 1.0.0 版本提供了该功能。因为 confluent 公司依赖的 c kafka-client 已经实现了该功能。)
我们可以在 confluent-python 中设置
enable.idempotence=true When set totrue
, the producer will ensure that messages are successfully produced exactly once and in the original produce order. The following configuration properties are adjusted automatically (if not modified by the user) when idempotence is enabled:max.in.flight.requests.per.connection=5
(must be less than or equal to 5),retries=INT32_MAX
(must be greater than 0),acks=all
,queuing.strategy=fifo
. Producer instantation will fail if user-supplied configuration is incompatible.
Type: boolean
就可以开启生产者幂等模式。开启之后 broker 会帮我们做消息去重。具体的实现是 broker 端会通过一些字段来判断消息是否重复,并且会将这些重复消息丢弃掉。我并没有看过这一块 broker 的实现原理,所以感觉实现应该会比我说的复杂。功能上可以理解成这样即可。这个功能虽然看起来很叼,但是他只能保证单个分区的幂等性。也就是说只有单个分区是能保证消息去重的,如果发到其他分区上将不能保证是幂等。另外这个特性也无法跨会话。如果 producer 重启,重新与 broker 建立会话,该特性也会失效。可能有人会说我擦,单个 partitions 去重有啥用?仔细想想 partitions 的实现,在不考虑重发的情况下如果我们基于 key 进行分区,那么同样的 key 消息一定会去到同样的 partitions 那么就达到了幂等的效果。
事务 Producer
事务 Producer 可以保证将消息原子性的写到多个分区中,要么全部写成功要么全部写失败。
很遗憾截止到目前为止 python 没有任何一个 client 实现了该特性 但是 confluent-python 承诺在 19年Q2-Q3 实现该功能
只能看下 java 客户端实现了。
设置 enable.idempotence=true
transactional.id 设置为一个值
此外生产者需要调整代码进行打包提交
producer.initTransactions();
try {
producer.beginTransaction();
producer.send(record1);
producer.send(record2);
producer.commitTransaction();
} catch (KafkaException e) {
producer.abortTransaction();
}
这里可以从名字看出来就是类似 MySQL 的 开启事务 发送事务 提交事务 终止事务
kafka 提供了全部成功 or 全部失败的事务保证。这是怎么实现的 我还蛮好奇。。。回头查阅一下资料看看。
Reference:
https://github.com/confluentinc/confluent-kafka-python/releases Confluent's Python client For Apache Kafka
https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md librdkafka config
https://github.com/confluentinc/confluent-kafka-python/issues/357 Does python binding support exactly once semantics?
https://docs.confluent.io/current/clients/confluent-kafka-python/index.html confluent-kafka doc
Kafka 幂等生产者和事务生产者特性(讨论基于 kafka-python | confluent-kafka 客户端)的更多相关文章
- python confluent kafka客户端配置kerberos认证
kafka的认证方式一般有如下3种: 1. SASL/GSSAPI 从版本0.9.0.0开始支持 2. SASL/PLAIN 从版本0.10.0.0开始支持 3. SASL/SCRAM-SHA- ...
- kafka 幂等生产者及事务(kafka0.11之后版本新特性)
1. 幂等性设计1.1 引入目的生产者重复生产消息.生产者进行retry会产生重试时,会重复产生消息.有了幂等性之后,在进行retry重试时,只会生成一个消息. 1.2 幂等性实现1.2.1 PID ...
- 二、Kafka基础实战:消费者和生产者实例
一.Kafka消费者编程模型 1.分区消费模型 分区消费伪代码描述 main() 获取分区的size for index =0 to size create thread(or process) co ...
- RabbitMQ(5) 事务&生产者确认
事务&生产者确认 一般情况下,生产者将消息发送后,继续进行别的业务逻辑处理.消息从生产者发送后,可能由于网络原因丢失,也可能因为RabbitMQ服务端奔溃未被处理...总之,对于 消息是否安全 ...
- kafka同步生产者和异步生产者深入剖析
什么是kafka同步生产者,什么是kafka异步生产者? 比如这里某个topic有3个分区. kafka同步生产者:这个生产者写一条消息的时候,它就立马发送到某个分区去. kafka异步生产者:这个 ...
- 基于Kafka消息驱动最终一致事务(二)
实现用例分析 上篇基于Kafka消息驱动最终一致事务(一)介绍BASE的理论,接着我们引入一个实例看如何实现BASE,我们会用图7显示的算法实现BASE.
- 基于Kafka消息驱动最终一致事务(一)
基本可用软状态最终一致事务 本用例分两个数据库分别是用户库和交易库,不使用分布式事务,使用基于消息驱动实现基本可用软状态最终一致事务(BASE).现在说明下事务逻辑演化步骤,尊从CAP原则,即分布式系 ...
- Kafka设计解析(二十一)关于Kafka幂等producer的讨论
转载自 huxihx,原文链接 关于Kafka幂等producer的讨论 众所周知,Kafka 0.11.0.0版本正式支持精确一次处理语义(exactly once semantics,下称EOS) ...
- 关于Kafka幂等producer的讨论
众所周知,Kafka 0.11.0.0版本正式支持精确一次处理语义(exactly once semantics,下称EOS).Kafka的EOS主要体现在3个方面: 幂等producer:保证发送单 ...
随机推荐
- SpringBoot--对SpirngMVC的自动配置
SpringBoot对SpringMVC提供了许多自动配置 Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver b ...
- oracle数据库 TIMESTAMP(6)时间戳类型
时间戳类型,参数6指的是表示秒的数字的小数点右边可以存储6位数字,最多9位.由于时间戳的精确度很高,我们也常常用来作为版本控制. 插入时,如下方式:insert into test4 values(t ...
- web项目服务器安装及配置(虚拟机centOS7)
一.安装VMware(如需) 1.首先下载VMware虚拟机,地址: https://www.vmware.com/products/workstation-pro/workstation-pro-e ...
- 'adb' 不是内部或外部命令,也不是可运行的程序 或批处理文件—解决方法
Windows键 + R → 输入cmd → 输入adb,提示“adb不是内部或外部命令,也不是可运行的程序 或批处理文件“,错误信息如下: 解决方法: 此电脑(右击)→ 属性 → 高级系统设置 → ...
- c# Queue 类
- Linux 进程IO杂项
Linux 进程IO杂项 本文结合一个 pwn 例题,在分析例题的过程中穿插介绍相关知识. 例题来源:PWNABLE.KR 网站,Toddler's Bottle 小节,习题 input. 例题内容: ...
- Kali下进行局域网断网攻击
今天我就来演示一下在kali下的局域网断网攻击,即ARP地址欺骗,下图所要用到的arp地址欺骗状态图: 则: 第一步:假设主机A访问某网站,那么要告知某网站我的IP和MAC地址,但这是以广播的方式告知 ...
- Vuex状态管理总结
一.什么是 Vuex 1.Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 2.Vuex 采用集中式存储和管理应用中所有组件的状态 3.Vuex 应用的核心是 store(仓库)-- 包 ...
- synchronized(修饰方法和代码块)
synchronized(修饰方法和代码块) 1. 含义 synchronized 是同步锁,用来实现互斥同步. 在 Java 中,关键字 synchronized 可以保证在同一个时刻,只有一个线程 ...
- javax.servlet.ServletException: Circular view path [index]: would dispatch back to the current handler URL [/pay/index] again. Check your ViewResolver setup!
2019-08-08 17:12:03.544 ERROR 13748 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Se ...