Apache Kafka消息传递策略

news2025/1/19 21:04:15

kafka消息传递策略

  • 微信公众号:阿俊的学习记录空间
  • 小红书:ArnoZhang
  • wordpress:arnozhang1994
  • 博客园:arnozhang
  • CSDN:ArnoZhang1994

现在我们了解了一些关于生产者和消费者的工作原理,接下来讨论Kafka在生产者和消费者之间提供的策略保证。显然,消息传递可以提供多种保证:

  • 最多一次——消息可能会丢失,但从不会被重新发送。
  • 至少一次——消息不会丢失,但可能会被重复发送。
  • 精确一次——这是理想状态,每条消息仅传递一次且不会重复。

需要注意的是,这可以分解为两个问题:发布消息的持久性保证和消费消息时的保证。

很多系统声称提供“精确一次”的传递策略,但仔细阅读细则后会发现,这些声明大多是误导性的(例如,在生产者或消费者失败的情况下、存在多个消费者进程时、或磁盘上的数据可能丢失时,这些保证不再成立)。

Kafka 的策略相对简单。当发布消息时,我们有一个“提交”消息到日志的概念。一旦消息被提交,只要其中一个复制该消息的分区的broker仍然“存活”,消息就不会丢失。目前我们假设一个理想、无损的broker,来理解生产者和消费者的保证。当生产者尝试发布消息并遇到网络错误时,它无法确定错误发生在消息提交之前还是之后。这类似于向数据库插入带有自生成键的记录。

在0.11.0.0版本之前,如果生产者未能收到消息已提交的响应,它几乎只能重新发送消息。这提供了至少一次的传递策略,因为在重发时,原始请求可能已经成功,消息可能会再次写入日志。从0.11.0.0版本开始,Kafka 生产者还支持幂等传递选项,保证重新发送不会导致日志中出现重复条目。为实现这一点,broker会为每个生产者分配一个ID,并通过生产者在每条消息中附带的序列号去重。从0.11.0.0版本开始,生产者还支持使用类似事务的策略将消息发送到多个topic分区:要么所有消息都成功写入,要么都不会写入。其主要用例是Kafka topic间的精确一次处理(将在下文描述)。

并非所有用例都需要如此强的保证。对于对延迟敏感的用例,我们允许生产者指定所需的持久性级别。如果生产者指定希望等待消息被提交,这可能需要约10毫秒。然而,生产者也可以指定完全异步发送,或者仅等待主副本(而不一定是所有副本)接收消息。

现在从消费者的角度描述策略。所有副本都有完全相同的日志,且有相同的偏移量。消费者控制它在日志中的位置。如果消费者从未崩溃,它可以将位置存储在内存中,但如果消费者失败,且我们希望另一个进程接管该topic分区,那么新进程需要选择一个合适的位置开始处理。假设消费者读取了一些消息,它有几种处理消息和更新其位置的选项:

  1. 它可以读取消息,然后保存其在日志中的位置,最后处理消息。在这种情况下,消费者进程可能在保存其位置后但在处理消息结果之前崩溃。接管的进程会从已保存的位置开始处理,即使某些消息尚未被处理。这对应于“最多一次”策略,因为在消费者故障的情况下,消息可能不会被处理。
  2. 它可以先读取消息,处理消息,最后保存其位置。在这种情况下,消费者进程可能在处理完消息后但在保存位置之前崩溃。接管的新进程会接收到已经处理过的前几条消息。这对应于“至少一次”策略。在许多情况下,消息有一个主键,因此更新是幂等的(即接收同一条消息两次只会覆盖之前的记录)。

那么关于精确一次策略呢(即我们真正需要的)?当从Kafka topic消费并向另一个topic生产消息时(如在Kafka Streams应用中),我们可以利用0.11.0.0中提到的新事务性生产者功能。消费者的位置被存储为一个topic中的消息,因此我们可以将偏移量写入Kafka,并与接收已处理数据的输出topic一起使用同一事务。如果事务被中止,消费者的位置将回滚到旧值,输出topic中的数据将对其他消费者不可见,这取决于它们的“隔离级别”。在默认的“未提交读取”隔离级别下,消费者可以看到所有消息,即使这些消息是中止事务的一部分;而在“已提交读取”中,消费者只会返回已提交事务中的消息(以及未参与事务的消息)。

当写入外部系统时,限制在于需要协调消费者的位置与实际存储的输出。经典的实现方法是将消费者位置的存储与消费者输出的存储之间引入两阶段提交。但这可以通过让消费者将偏移量存储在与输出相同的地方来更简单且通用地解决。这种方法更好,因为消费者可能写入的许多输出系统不支持两阶段提交。作为一个示例,Kafka Connect连接器会将数据写入HDFS,并存储其读取的数据的偏移量,以保证数据和偏移量要么一起更新,要么都不更新。我们对许多其他需要这些更强策略的数据系统采用了类似的模式,而这些消息没有主键来实现去重。

因此,Kafka 在Kafka Streams中有效支持了精确一次传递,并且事务性生产者/消费者通常可以用于在Kafka topic之间传输和处理数据时提供精确一次传递。对于其他目标系统,通常需要这些系统的配合,但Kafka提供的偏移量使实现这一点变得可行(另见Kafka Connect)。否则,Kafka默认保证至少一次传递,并允许用户通过禁用生产者的重试功能和在消费者处理消息批次前提交偏移量来实现最多一次传递。

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

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

相关文章

Java:玩家打怪小游戏

今天,我们尝试用Java来做一个“打怪小游戏”,听名字就知道,我们是应该创建几个成员和怪物,还有知道知道成员和怪物的血量,一次攻击的伤害等等。。当然我们的游戏攻击模式是“回合制”(其实是别的方法&#…

SpringCloud-OpenFeign-服务接口调用

是什么 把需要暴露的api使用接口来暴露,客户端需要调用的时候,直接查看这个接口中有没有就可以了 通用步骤 架构说明 common模块 common 引入 openfeign 新建服务接口类 FeignClient(value "cloud-payment-service") // 服务名 public i…

【数据采集工具】Flume从入门到面试学习总结

国科大学习生活(期末复习资料、课程大作业解析、大厂实习经验心得等): 文章专栏(点击跳转) 大数据开发学习文档(分布式文件系统的实现,大数据生态圈学习文档等): 文章专栏(点击跳转&…

# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十三)--权限设置注意事项和属主属组设置sudo操作

linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十三)–权限设置注意事项和属主属组设置sudo操作 一、linux 权限设置 特殊注意事项 1、使用root用户创建一个文件夹(/oo),权限默认&…

前端知识点总和

目录 一、canvas: (1)创建canvas标签: (2)使用JS获得这个canvas标签的DOM对象: (3)决定是画二维还是三维的画: (4)API&#xff1…

企业防止信息泄露的措施有哪些?10个防止信息泄露小技巧分享给你

在数字化时代,企业面临的安全挑战日益严峻,尤其是信息泄露问题。一旦企业内部或外部的敏感信息遭到泄露,不仅会造成巨大的经济损失,还可能影响企业声誉、客户信任,甚至可能引发法律纠纷。为了有效防止信息泄露&#xf…

使用 SQLmap 自动化检测 SQL 注入

使用 SQLmap 自动化检测 SQL 注入是一种常见的渗透测试技术。SQLmap 是一个强大的开源工具,可以自动检测和利用 SQL 注入漏洞,提取数据库信息,并接管目标数据库服务器。下面是如何使用 SQLmap 进行自动化检测 SQL 注入的基本步骤。 准备环境…

RabbitMQ 入门(七)SpringAMQP五种消息类型

一、Topic Exchange(消息模式) TopicExchange 与DirectExchange类似,区别在于routingKey可以是多个单词的列表,并且以.分割。 Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过…

Spring WebFlux 核心原理(2-1)

1、Spring 响应式编程 1.1、早期响应式解决方案 响应式编程是构建响应式系统的主要候选方案。Spring 4.x 引入了 ListenableFuture 类,它扩展了 Java Future,并且可以基于 HTTP 请求实现异步执行操作。但是只有少数 Spring 4.x 组件支持新的 Java 8 Com…

Nginx(Linux):服务器版本升级和新增模块

目录 1、概述2、使用Nginx服务信号完成Nginx升级2.1 备份当前版本的Nginx2.2 向服务器导入新的Nginx2.3 向服务器导入新的Nginx2.4 停止老版本Nginx 3、使用Nginx安装目录的make命令完成升级3.1 备份当前版本的Nginx3.2 向服务器导入新的Nginx3.3 执行更新命令 1、概述 如果想…

24最新ComfyUI插件与Lora的下载及使用指南!

前言 本节我们介绍ComfyUI插件和Lora的下载及使用方式。 1. 安装 1.1 Checkpoint安装 将从前面介绍的模型下载平台下载后,放在ComfyUI/models/checkpoints文件夹下。 所有的AI设计工具,安装包、模型和插件,都已经整理好了,&am…

【vue自定义指令】骨架屏指令

场景 预加载的过程中,数据还未请求到,dom已经渲染出来了? 展示效果 实现 封装指令(代码块1) app引入(代码块2)使用(代码块3) 代码 封装 ​ import { reactive, wa…

Spark全网最全总结

Spark 产生之前,已经有 MapReduce 这类非常成熟的计算系统存在了,并提供 了高层次的 API(map/reduce),把计算运行在集群中并提供容错能力,从而实现 分布式计算。 虽然 MapReduce 提供了对数据访问和计算的抽象&#xff0c…

一个月学会Java 第13天 抽象类与接口

Day13 抽象类与接口 通过了前面的学习,我们已经掌握了面向对象的基础 继承 封装 多态 第一章 抽象类 接下来,我们要对面向对象学习高级的部分,我们先要学到的就是抽象类,听名字也能想到,肯定很抽象,那我们先…

电力电子技术(二)

三相可控整流电路:(主要包括三相半波和三相桥式) (一)三相半波: (1.1电阻性负载) 右侧第三个图代表VT1晶闸管的流经电流波形,一个周期仅导通一次:晶闸管导…

Netty讲解与案例

1.Netty简介: 官网:https://netty.io/ Netty 是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和精简了 TCP 和 UDP 套接字服务器等网络编程。 “快速简便”并不意味着最终的应用程序会存在…

Halcon 使用二维像素分类对图像进行分割

文章目录 算子histo_2dim 计算双通道灰度值图像的直方图class_2dim_sup 使用二维像素分类对图像进行分割 示例 算子 histo_2dim 计算双通道灰度值图像的直方图 histo_2dim(Regions, ImageCol, ImageRow : Histo2Dim : : )Regions (输入对象):在此区域内计算直方图…

腾讯云视立方开通各项云服务相关

云直播 如何开通云直播服务? 进入 云直播管理控制台,进入腾讯云直播服务开通页,查看相关协议并勾选同意,单击申请开通即可开通云直播服务。 。 如何开启流防盗链 KEY? 推流防盗链 KEY 是为了确保只有您的 App 用户…

dockerfile 用法全解析

FROM 构建基于alpine的镜像,单条执行就是复制了一个apline镜像(除了FROM其他都是非必须的) WORKDIR 是之指定接下来的shell语句是运行在哪个路径下,没有就会创建目录 COPY 将宿主机指定目录的文件拷贝到镜像指定目录 (ADD 源地址还可以url…

[LeetCode] 662. 二叉树最大宽度

题目描述: 给你一棵二叉树的根节点 root ,返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结…