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. ubuntu 16.04 循环登陆问题

    换了个titan x重装显卡驱动失败之后一直循环登陆,试了N种处理显卡驱动的方法,并没有啥用. 最后查看了一下.Xerrer文件(具体的文件名我给忘记了),发现是.Xauthority. 现象:在Ub ...

  2. Matlab图形绘制

    图形绘制 离散函数图形: 例:离散数据和离散函数可视化(离散数据作图方式) X1=[,,,,,,,,,,,,,,,,,,,]; Y1=[,,,,,,,,,,,,,,,,,,,]; figure() p ...

  3. IOC+EF+Core项目搭建EF封装(一)

    添加应用Microsoft.EntityFrameworkCore:Microsoft.EntityFrameworkCore.Design:Microsoft.EntityFrameworkCore ...

  4. 每周分享五个 PyCharm 使用技巧(六)

    大家好,今天我又来给大家更新 PyCharm 的使用技巧. 从今年3月24号开始一直到今天,将近四个月的时间.包括本篇,一共更新了6篇文章,每篇 5 个小技巧,总计 30 个. 这30个使用技巧,全部 ...

  5. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

  6. unity4.3.4firedrillonline项目首次整合问题总结

    零.资源导入后把所有资源模型拖到场景中去,并reset Transform,使场景展现原有样子. 一.资源导入之后发现项目场景是黑的,添加灯光之后场景中大部分仍然是黑的(并没有光照的效果) 可能原因: ...

  7. Java中重载(overloading)和重写(Overriding)的区别

    一:方法的重载 (1)方法重载指在类中定义方法名相同,参数不同的不同的多个方法(返回值类型可随意,不能以返回类型作为重载函数的区分标准). 参数不同表现: 1.参数的个数不同 2.参数的类型不同 3. ...

  8. Android笔记(四十六) Android中的数据存储——XML(二)PULL解析

    PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText()从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDo ...

  9. Kubernetes-Istio之Sidecar自动注入

    前提: (官方提供) 1):确认使用的是Kubernetes服务器的受支持版本( 1.13.1.14.1.15):kubectl (官方提供,应该是1.13版本以上,我的是1.16版本) kubect ...

  10. [IC]浅谈嵌入式MCU软件开发之中断优先级与中断嵌套

    转自:https://mp.weixin.qq.com/s?__biz=MzI0MDk0ODcxMw==&mid=2247483680&idx=1&sn=c5fd069ab3f ...