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 to true, 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=allqueuing.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 客户端)的更多相关文章

  1. python confluent kafka客户端配置kerberos认证

    kafka的认证方式一般有如下3种: 1. SASL/GSSAPI  从版本0.9.0.0开始支持 2. SASL/PLAIN   从版本0.10.0.0开始支持 3. SASL/SCRAM-SHA- ...

  2. kafka 幂等生产者及事务(kafka0.11之后版本新特性)

    1. 幂等性设计1.1 引入目的生产者重复生产消息.生产者进行retry会产生重试时,会重复产生消息.有了幂等性之后,在进行retry重试时,只会生成一个消息. 1.2 幂等性实现1.2.1 PID ...

  3. 二、Kafka基础实战:消费者和生产者实例

    一.Kafka消费者编程模型 1.分区消费模型 分区消费伪代码描述 main() 获取分区的size for index =0 to size create thread(or process) co ...

  4. RabbitMQ(5) 事务&生产者确认

    事务&生产者确认 一般情况下,生产者将消息发送后,继续进行别的业务逻辑处理.消息从生产者发送后,可能由于网络原因丢失,也可能因为RabbitMQ服务端奔溃未被处理...总之,对于 消息是否安全 ...

  5. kafka同步生产者和异步生产者深入剖析

    什么是kafka同步生产者,什么是kafka异步生产者? 比如这里某个topic有3个分区. kafka同步生产者:这个生产者写一条消息的时候,它就立马发送到某个分区去.  kafka异步生产者:这个 ...

  6. 基于Kafka消息驱动最终一致事务(二)

    实现用例分析 上篇基于Kafka消息驱动最终一致事务(一)介绍BASE的理论,接着我们引入一个实例看如何实现BASE,我们会用图7显示的算法实现BASE.

  7. 基于Kafka消息驱动最终一致事务(一)

    基本可用软状态最终一致事务 本用例分两个数据库分别是用户库和交易库,不使用分布式事务,使用基于消息驱动实现基本可用软状态最终一致事务(BASE).现在说明下事务逻辑演化步骤,尊从CAP原则,即分布式系 ...

  8. Kafka设计解析(二十一)关于Kafka幂等producer的讨论

    转载自 huxihx,原文链接 关于Kafka幂等producer的讨论 众所周知,Kafka 0.11.0.0版本正式支持精确一次处理语义(exactly once semantics,下称EOS) ...

  9. 关于Kafka幂等producer的讨论

    众所周知,Kafka 0.11.0.0版本正式支持精确一次处理语义(exactly once semantics,下称EOS).Kafka的EOS主要体现在3个方面: 幂等producer:保证发送单 ...

随机推荐

  1. WPF内嵌网页的两种方式

    在wpf程序中,有时会内嵌网页.内嵌网页有两种方法,一种是使用wpf自带WebBrowser控件来调用IE内核,另一种是使用CefSharp包来调用chrom内核. 一.第一种使用自带WebBrows ...

  2. java之struts2的配置讲解(2)

    在 java之struts框架入门教程 基础上,进行下列操作 1.结构对比 原来的项目结构图 现在的结构图 即从结构上可以看出,在HelloStruts项目中增加了config 文件夹(Source ...

  3. 父元素设置min-height子元素设置100%问题

    问题:父元素设置min-height子元素高度设置100%取不到值,这是因为子元素 div设置 height:100%: 只有当父级元素满足min-height:1000px;设置的条件才触发: 浏览 ...

  4. jmeter用什么查看结果报告

    JMeter查看测试结果的方法很多,最常用的几种是:察看结果树.聚合报告.图形报表.邮件观察仪等.

  5. springboot整合ActiveMQ1(基本使用)

    基本使用,https://www.tapme.top/blog/detail/2018-09-05-10-38 主备模式,https://www.tapme.top/blog/detail/2018- ...

  6. 行内块inline-block元素之间出现空白间隙原因及解决办法

    首先,来看下具体的问题,下面是用inline-block布局实现的两边固定宽度,中间自适应的html代码: 1 2 3 4 5 6 7 8 9 <section class="layo ...

  7. SQL SERVER-Exclusive access could not be obtained because the database is in use. (Microsoft.SqlServer.SmoExtended)

    Q:先在一个实例中恢复一个数据A,然后又想在恢复一次,取别名为A2,这是报异常SQL SERVER-Exclusive access could not be obtained because the ...

  8. spring事务什么时候会自动回滚

    在java中异常的基类为Throwable,他有两个子类xception与Errors.同时RuntimeException就是Exception的子类,只有RuntimeException才会进行回 ...

  9. Linux下环境变量设置 (转)

    Linux下环境变量设置 1.在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错 ...

  10. c# 日期和时间System.DateTime