Kafka Producer幂等性

Kafka Producer幂等性Producer 幂等性在 Kafka 中 Producer 默认不是幂等性的 但我们可以创建幂等性 Producer 它其实是 0 11 0 0 版本引入的新功能 在此之前 Kafka 向分区发送数据时 可能会出现同一条消息被发送了多次 导致消息重复的情况 在 0 11 之后 指定 Producer 幂等性的方法很简单 仅需要设置一个参数即可 即 props put enable idemp

Producer幂等性

在 Kafka 中,Producer 默认不是幂等性的,但我们可以创建幂等性 Producer。它其实是 0.11.0.0 版本引入的新功能。在此之前,Kafka 向分区发送数据时,可能会出现同一条消息被发送了多次,导致消息重复的情况。在 0.11 之后,指定 Producer 幂等性的方法很简单,仅需要设置一个参数即可,即 props.put(“enable.idempotence”, ture),或 props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。

enable.idempotence 被设置成 true 后,Producer 自动升级成幂等性 Producer,其他所有的代码逻辑都不需要改变。Kafka 自动帮你做消息的重复去重。底层具体的原理很简单,就是经典的用空间去换时间的优化思路,即在 Broker 端多保存一些字段。当 Producer 发送了具有相同字段值的消息后,Broker 能够自动知晓这些消息已经重复了,于是可以在后台默默地把它们“丢弃”掉。当然,实际的实现原理并没有这么简单,但你大致可以这么理解。

看上去,幂等性 Producer 的功能很酷,使用起来也很简单,仅仅设置一个参数就能保证消息不重复了,但实际上,我们必须要了解幂等性 Producer 的作用范围。

首先,它只能保证单分区上的幂等性,即一个幂等性 Producer 能够保证某个主题的一个分区上不出现重复消息,它无法实现多个分区的幂等性。其次,它只能实现单会话上的幂等性,不能实现跨会话的幂等性。这里的会话,你可以理解为 Producer 进程的一次运行。当你重启了 Producer 进程之后,这种幂等性保证就丧失了。

那么你可能会问,如果我想实现多分区以及多会话上的消息无重复,应该怎么做呢?答案就是事务(transaction)或者依赖事务型 Producer。这也是幂等性 Producer 和事务型 Producer 的最大区别!

事务

Kafka 的事务概念类似于我们熟知的数据库提供的事务。在数据库领域,事务提供的安全性保障是经典的 ACID,即原子性(Atomicity)、一致性 (Consistency)、隔离性 (Isolation) 和持久性 (Durability)。

当然,在实际场景中各家数据库对 ACID 的实现各不相同。特别是 ACID 本身就是一个有歧义的概念,比如对隔离性的理解。大体来看,隔离性非常自然和必要,但是具体到实现细节就显得不那么精确了。通常来说,隔离性表明并发执行的事务彼此相互隔离,互不影响。经典的数据库教科书把隔离性称为可串行化 (serializability),即每个事务都假装它是整个数据库中唯一的事务。

提到隔离级别,这种歧义或混乱就更加明显了。很多数据库厂商对于隔离级别的实现都有自己不同的理解,比如有的数据库提供 Snapshot 隔离级别,而在另外一些数据库中,它们被称为可重复读(repeatable read)。好在对于已提交读(read committed)隔离级别的提法,各大主流数据库厂商都比较统一。所谓的 read committed,指的是当读取数据库时,你只能看到已提交的数据,即无脏读。同时,当写入数据库时,你也只能覆盖掉已提交的数据,即无脏写。

Kafka 自 0.11 版本开始也提供了对事务的支持,目前主要是在 read committed 隔离级别上做事情。它能保证多条消息原子性地写入到目标分区,同时也能保证 Consumer 只能看到事务成功提交的消息。下面我们就来看看 Kafka 中的事务型 Producer。

事务型 Producer

事务型 Producer 能够保证将消息原子性地写入到多个分区中。这批消息要么全部写入成功,要么全部失败。另外,事务型 Producer 也不惧进程的重启。Producer 重启回来后,Kafka 依然保证它们发送消息的精确一次处理。

设置事务型 Producer 的方法也很简单,满足两个要求即可:

  • 和幂等性 Producer 一样,开启 enable.idempotence = true。
  • 设置 Producer 端参数 transctional. id。最好为其设置一个有意义的名字。

此外,你还需要在 Producer 代码中做一些调整,如这段代码所示:

 

producer.initTransactions();

 

try {

 

   producer.beginTransaction();

 

   producer.send(record1);

 

   producer.send(record2);

 

   producer.commitTransaction();

 

} catch (KafkaException e) {

 

   producer.abortTransaction();

 

}

和普通 Producer 代码相比,事务型 Producer 的显著特点是调用了一些事务 API,如 initTransaction、beginTransaction、commitTransaction 和 abortTransaction,它们分别对应事务的初始化、事务开始、事务提交以及事务终止。

这段代码能够保证 Record1 和 Record2 被当作一个事务统一提交到 Kafka,要么它们全部提交成功,要么全部写入失败。实际上即使写入失败,Kafka 也会把它们写入到底层的日志中,也就是说 Consumer 还是会看到这些消息。因此在 Consumer 端,读取事务型 Producer 发送的消息也是需要一些变更的。修改起来也很简单,设置 isolation.level 参数的值即可。当前这个参数有两个取值:

  1. read_uncommitted:这是默认值,表明 Consumer 能够读取到 Kafka 写入的任何消息,不论事务型 Producer 提交事务还是终止事务,其写入的消息都可以读取。很显然,如果你用了事务型 Producer,那么对应的 Consumer 就不要使用这个值。
  2. read_committed:表明 Consumer 只会读取事务型 Producer 成功提交事务写入的消息。当然了,它也能看到非事务型 Producer 写入的所有消息。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218917.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午11:10
下一篇 2026年3月17日 下午11:10


相关推荐

  • 【转载】教你使用 Reflexil 反编译.NET

    【转载】教你使用 Reflexil 反编译.NET

    2021年11月21日
    43
  • c语言的stl库_c语言string库

    c语言的stl库_c语言string库今天推荐一个函数库glib注意不是glibc https://developer.gnome.org/glib/一直在抱怨,标准C中为什么没有类似于STL的标准容器,让全世界的程序员在数以万次的重复实现它们。不过,还算走运,有了glib,恶梦在此终结了。glib提供了动态数组、单/双向链表、哈希表、多叉树、平衡二叉树、字符串等常用容器,完全是面向对象设计的,实现得非常精致。

    2022年10月15日
    3
  • 计算机分子模拟聚乙烯,高分子物理实验思考题@中科大.pdf[通俗易懂]

    计算机分子模拟聚乙烯,高分子物理实验思考题@中科大.pdf[通俗易懂]高分子物理实验思考题@中科大1.为什么在计算机模拟实验1(用“分子模拟”软件构建全同立构聚丙烯分子、聚乙烯分子并计算它们末端的直线距离)中我们一再把第一个碳原子到最后一个碳原子的距离叫做末端距离,而不称通常所说的根均方末端距?2.你对计算机在高分子科学中的应用有多少了解?3.在考虑高分子链内旋转空间位阻时,高分子链的尺寸如何变化?4.在“二维高分子链形态的计算机模拟”实验中采用的是改进后…

    2022年5月25日
    34
  • 无刷电机的驱动

    无刷电机的驱动原文地址:http://www.dzkf.cn/html/zonghejishu/2009/0319/3706.html前言:   有关本文所谈论的无刷电机内容,只涉及低速飞行类航模电调的小功率无传感器应用,讲解的理论比较浅显易懂,旨在让初学者(象笔者本人)能够对无刷电机有一个比较快的认识,掌握基本原理和控制方法,可以在短时间内达到应用目的。理论性的内容涉及模拟电路知识、基础电子线路

    2022年8月30日
    6
  • JAVA中调用CMD命令,并输出运行结果

    JAVA中调用CMD命令,并输出运行结果

    2021年11月16日
    47
  • C语言输出的字体和背景颜色你会设置吗!

    C语言输出的字体和背景颜色你会设置吗!学了那么久C语言,难免会所写对程序输出内容颜色感到单调,总想整点酷的东西………

    2022年6月20日
    28

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号