Kafka如何实现精确一次语义

news2024/11/16 7:31:43
4a93a4e9b5b2b7f5acd6fa3cab55cee6.png

精确一次交付保证是关于消息传递最具争议性的话题之一,因此也是最复杂的任务之一。然而,几年前,Kafka团队宣布他们实现了这一目标,让我们深入研究一下他们的实现方式以及存在的限制。

首先,值得定义一下这些交付语义是什么。通常有三种使用的语义:

•至少一次:系统保证消息被接收,但不能保证只接收一次。•至多一次:系统不保证消息被接收,但如果接收到,则只接收一次。•精确一次:综合了前两种保证,即消息被接收且只接收一次。

当然,“精确一次”是最理想的,但同时也是最难实现的,只有在生产者、代理和消费者共同合作的情况下才可能实现。这个概念在我之前的文章中有所解释。

Kafka Streams

一个非常重要但经常被忽略的细节是,Kafka仅在Kafka Streams中支持精确一次交付。要启用它,只需将配置选项processing.guarantee从默认选项at_least_once更改为exactly_once_v2。

但是,即使在Streams应用程序中也存在限制。如果您的消费者从Kafka中读取事件并在关系型数据库中进行更改,Kafka不会回滚它。如果您的消费者发送短信通知,即使使用Kafka Streams库,Kafka也无法回滚这些通知。这些都是开发人员应始终记住的限制。

为什么要谈论“回滚”变更?这是因为处理消息的精确一次的唯一方法是在一个事务中完成。

那么,什么是Kafka Streams以及为什么可以使其具有事务性?Kafka Streams是用于构建应用程序和服务的客户端库,其中输入和输出数据存储在Kafka集群中[1]。这就是关键所在。

122f3a26f27582efc6870aea28c7248a.png

Kafka Streams应用程序循环

Kafka Streams应用程序实现了读取-处理-写入的循环,具体步骤如下:

1.从输入主题读取消息。2.调用处理函数以处理接收到的消息,更新内部状态。3.生成输出消息并将其发送到输出主题(或多个主题)。4.等待来自Kafka的

输出消息确认。

1.提交输入主题的偏移量,表示消息已成功处理。

您可能知道,所有偏移量都存储在隐藏的Kafka主题中,Streams应用程序的内部状态也存储在名为状态存储的内部Kafka存储中。因此,所有的更改都存储在同一个Kafka集群中,并且可以在单个事务内进行管理和回滚。

8b8b9127cdbc1ac065221929d4f10e86.png

Streams应用程序数据存储

这里的状态存储有些过于简化,实际上更为复杂,因为它包含了日志变更主题和RocksDB实例,但我们可以在这里忽略这些细节。关于这个内部存储的更多详细信息可以在Kafka维基中找到。

幂等生产者

让我们回到开始的地方。一切可能出错的第一阶段是消息的生产。生产者将消息发送到代理并接收确认,表示代理已成功接收。如果没有接收到确认,生产者会再次发送相同的消息。

834620956525baf5b90d556c92e7e49f.png

Kafka生产者无法接收确认

上面的图中,您可以看到三种情况,生产者没有从代理那里接收到确认,并决定再次发送消息的情况:

1.代理没有接收到消息,因此显然没有确认。2.代理接收到了消息,但是发送确认失败。3.代理接收到了消息并成功发送了确认,但是这超过了生产者的等待超时时间。

生产者在所有这些情况下都会进行重试,但在其中两种情况(2和3)中,会导致重复。

无论是我还是Kafka的开发人员,都不知道如何解决生产者端的这个问题。因此,所有的去重工作都由代理完成,代理保证消息只会写入日志一次。为了实现这一点,消息被分配了一个序列号(我在关于幂等消费者模式的文章中描述了类似的方法)。所以,准确地说,并不是幂等的生产者,而是智能的代理完成了消息的去重工作。

要在Kafka中启用此功能,只需将生产者配置为enable.idempotence=true。

Kafka事务的工作原理

在消息被写入Kafka日志并且代理保证没有重复之后,应该在一个事务中处理消息并写入下一个主题。但是如何做到呢?

Kafka事务是写入日志的一组更改,日志本身存储在内部

Kafka主题中。此日志由一个名为事务协调器(Transaction Coordinator)的特殊实体管理。要调用事务,必须完成以下几个步骤:

1.消费者找到事务协调器。这是在应用程序启动时发生的。它将其配置的事务ID(如果存在)发送到协调器,并接收生产者ID。这在应用程序重新启动并尝试使用相同的事务ID进行注册时非常重要。当重新启动的应用程序启动新事务时,事务协调器会中止前一个实例启动的所有挂起事务。2.当应用程序消费新消息时,它启动事务。3.当应用程序将消息写入其他任何主题时,它将此信息发送给其事务协调器。协调器在其内部主题中存储有关所有更改的分区的信息。

这是一个重要的细节。使用Kafka Streams API,您不必手动将这些消息发送到协调器,Streams库将为您完成。但是,如果您直接将消息写入主题,则不会将其写入事务日志,即使此主题位于同一个集群中。

有关事务的另一个重要事项是,所有在事务期间写入的消息在事务提交之前都不会对消费者暴露。

1.事务提交或失败。如果中止,则协调器向内部主题的事务添加“中止”标记以及在事务期间写入的所有消息。2.当事务提交时,过程几乎相同。协调器向事务和所有消息添加了一个“提交”标记。该标记使得这些消息对消费者可用。

您不要忘记消费者的偏移量也存储在它们自己的主题中。这意味着提交偏移量与将消息写入输出主题相同。并且该消息也可以被标记为“中止”或“提交”,这将影响是否会再次消费相同的消息。显然,当标记为“提交”时,不会再次消费该消息;而当标记为“中止”时,整个事务将从头开始——消费消息。

事务协调器是否也是事务性的?

我尽量在文章中不过多地使用细节,以使其尽可能简单和清晰。但是还有一个值得一提的细节。事务协调器如何执行确切的事务提交?它应该更新事务、消息偏移量和输出消息,将其标记为“提交”。但是,如果在此过程中出现问题怎么办?当然,Kafka不会将一半的消息保留在已提交状态,另一半保留在挂起状态。

为了使提交更改一致,事务协调器会

首先将提交的消息写入分区协调器(Partition Coordinator)。这是另一个特殊实体,每个分区都有一个,负责维护分区的状态和偏移量。

分区协调器实现了与事务协调器相同的协议,并将消息更改存储在内部主题中。分区协调器只有在它们获得事务协调器的明确确认之后才能提交更改。否则,它们会将消息更改标记为“中止”,以便将来重试。

这种“两阶段提交”(Two-Phase Commit)的机制确保了事务的一致性。如果在提交更改之前出现问题,分区协调器不会提交更改,保持原子性。这种机制确保了Kafka的精确一次交付语义。

总结

Kafka通过结合幂等的生产者、事务和分区协调器等机制来实现精确一次交付的语义。这使得在消息的生产、处理和写入过程中能够保持一致性,并避免重复处理。

Kafka Streams提供了更简单的方式来使用精确一次交付,因为它将所有的状态和消息都存储在Kafka集群中,并利用了事务来确保处理的一致性。

然而,开发人员仍然需要注意一些限制和特殊情况,例如不能回滚外部系统的更改以及事务提交过程中的故障处理。

希望这篇文章对理解Kafka的精确一次交付机制有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/672977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMake在Linux服务器上进行编译与安装

CMake在Linux服务器上进行编译与安装 文章目录 CMake在Linux服务器上进行编译与安装[TOC](文章目录) 一、VScode 远程服务器连接1.服务器容器实例创建2.vscode 远程扩展部分下载(SSH端) 二、编译安装(时间较长)1.克隆项目到本地仓库2.进入CMa…

软考A计划-系统集成项目管理工程师-面向对象系统分析与设计-上

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

spring cloud 5大组件

Spring Cloud 5大组件 服务发现——Netflix Eureka 客服端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关——Netflix Zuul 分布式配置——Spring Cloud Config 一、业务场景介绍 先来给大家说一个业务场景,假设咱们现在开发一个电商网站&…

看 AI 如何抢救破烂文档

一、什么是非结构化数据二、非结构化数据分析三、 文档图像分析与预处理 修正图形偏移消除摩尔纹四、消除反光 反光原理Python 消除图片反光方法五、 版面分析与文档还原 5.1 物理版面 & 逻辑版面5.2 版面元素检查5.3 文档还原5.4 文档还原的应用六、整体小结 一、什么是非…

chatgpt赋能python:Python查询网站的SEO技巧及注意事项

Python查询网站的SEO技巧及注意事项 搜索引擎优化(SEO)是所有网站的头等大事,而对于Python查询网站来说,它更是必不可少的。在这篇文章中,我们将介绍一些Python查询网站的SEO技巧及注意事项,以帮助您提高网…

Elasticsearch分词器

前奏 es的chinese、english、standard等分词器对中文分词十分不友好,几乎都是逐字分词,对英文分词比较友好。 在kibana的dev tools中测试分词: POST /_analyze {"analyzer": "standard","text": "你太…

vue源码分析

1、获取vue源码 项目地址:https://github.com/vuejs/vue 2、文件结构 源码目录 3、调试环境搭建 安装依赖: npm i 安装rollup:npm i -g rollup 修改dev脚本,添加sourcemap,package.json "dev": "ro…

C语言建立并查集

一.树的存储方式 在知道并查集之前,我们得知道树的三种存储方式: 1.双亲表示法 双亲表示法 :双亲表示法是最简单的一种存储方式,它使用一个大小为n的一维数组来表示树中的n个节点。在数组中,每个元素存储该节点的父…

Linux内核态内存泄露检测工具——Kmemleak

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! …

Windows开始菜单栏处无法直接搜索软件

文章目录 1. 打开cmd,输入start powershell打开PowerShell,然后在PowerShell中输入下面的命令,之后重启电脑2. 修改注册表3. 开启Windows Search服务4. 可能是搜索进程被禁用了5. 开启Cortana5.1. 打开gpedit.msc 6. 使用疑难解答6.1. 选择其…

chatgpt赋能python:Python如何查找特定名称文件

Python如何查找特定名称文件 在计算机文件管理和互联网网络应用程序中,查找特定文件往往是一项必要的任务。在使用Python编程时,我们可以使用Python内置的os模块来查找特定名称的文件。本文将介绍如何使用Python查找特定名称的文件,并提供实…

一个例子带你了解MapReduce

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…

LTV-6314-ASEMI代理台湾光宝高速光耦LTV-6314

编辑:ll LTV-6314-ASEMI代理台湾光宝高速光耦LTV-6314 型号:LTV-6314 品牌:台湾光宝 封装:LSOP-6 引脚数量:6 类型:光耦 特性:台湾光宝、IGBT驱动器、储能专用光耦\高速光耦 …

如何看一块intel主板的配置的好坏

为什么写这篇文章 最近在挑13900k的主板,挑的眼花缭乱,发现主板市场不像CPU市场有那么清晰的产品线。 单拿微星一家的Z790来说,就包括但不限于以下型号 Z790 GAMINGZ790-PZ790-AZ790暗黑Z790刀锋 每一种的价格都不一样,更别弹还…

Golang每日一练(leetDay0104) 买卖股票最佳时机之含冷冻期、手续费

目录 309. 最佳买卖股票时机含冷冻期 Best-time-to-buy-and-sell-stock-with-cooldown 🌟🌟 714. 买卖股票的最佳时机含手续费 Best-time-to-buy-and-sell-stock-with-transaction-fee 🌟🌟 🌟 每日一练刷题专栏 …

读发布!设计与部署稳定的分布式系统(第2版)笔记08_自黑与放大

1. 自黑式攻击 1.1. 自黑只会偶尔成为人类的美德 1.2. 对系统来说,绝对不会推崇自黑 1.3. “自黑式攻击”是指系统或有人类参与的扩展系统联合外部对自身发起攻击 1.4. 好的营销可以随时杀死你 1.4.1. 并不是每个自黑的“伤口”,都可以归咎于营销部…

<C++> C++11新的类功能

C11新的类功能 1.默认成员函数 原来C类中,有6个默认成员函数: 构造函数析构函数拷贝构造函数拷贝赋值重载取地址重载const取地址重载 最后重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。 C11 新增了两个…

Uniapp 开发 ①(快速上手)

作者 : SYFStrive 博客首页 : HomePage 📜: 微信小程序 📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗 📌:觉得文章不错可以点点关注 &#x1f4…

Vue3在工作中使用的一些经验总结

1、隐藏el-tab-pane 设置隐藏 2、Vue中ref的使用 3、Vue中的api 4、component: () > import(‘/views/order/orderDetail‘), 5、ids selections.map((i) > i.ruleId); 6、路由配置的三种方式 项目中使用到的 7、Vue3新特性 8、template在Vue中的作用 9、…

电脑装机后使用Administrator作为电脑账号

目录标题 1 搜索cmd使用管理员权限运行(因为直接winr无法用权限打开)2 输入net user administrator /active:yes,之后系统会提示命令完成,通过这个指令就是让系统默认账户administrator成为超级管理员,方便接下来的操作…