哎,被这个叫做at least once的玩意坑麻了

【kafka系列】At Least Once语义 通过合理配置和业务设计,At-Least-Once可平衡可靠性与性能,是大多数场景的推荐选择。若Broker写入成功但网络超时,生产者重试会导致消息重复发送到Topic。失败(如消费者崩溃),下次启动时会重新拉取并处理同一消息,导致积分重复增加。复杂(需生产者、Broker、消费者协同)允许重复的业务(如日志采集)高(事务与协调开销) 阅读详情

前几天遇到一个生产问题,同一个数据在数据库里面被插入了两次,导致后续处理出现了一些问题。

当时我们首先检讨了自己,没有做好幂等校验。甚至还发现了一个低级错误:对应的表,针对订单号,这个业务上具有唯一属性的字段,连唯一索引都没有加。如果加了唯一索引,也不至于出现落库两次的情况。

然后拿着数据去问上游系统,为什么会出现同一个订单发起了两次的这种异常场景。

上游系统一听到我们的描述,立马就站出来解释:不可能,在没有人工介入的情况下,同一个单子,我们绝对不可能发送两次。在开发的过程中,我们还特意注意了这个场景。

但是我是不相信他们的“鬼话”,我更觉得这就是他们的一个 BUG。

既然争执不下了,那就拿事实说话。

日志就是事实。

于是我们一起查询了日志,最后的结果就更加奇怪了。

调用方确实只有一次调用日志。

但是我们接收方却收到了两次请求。

图片

通过图片也能看出来,我们之间是通过 MQ 异步交互的。

所以,自然而然的就把目光放到 MQ 上。

我们使用的 MQ 是一个叫做 SofaMQ 的玩意,比较冷门,但是有蚂蚁金服背书。

在官方文档的“常见问题”部分,有这样的描述:

图片

这句话你仔细品一下:可以保证消息不丢失,但是无法保证消息不重复。

言外之意是不是就是在说:为了保证消息不丢失,在我拿不准你到底有没有消费成功的情况下,我有可能针对的同一个消息再次发送。

再次发送,那不就是一个消息会被消费多次吗?

不就是我们遇到的这个问题吗?

然后我突然想起了一个曾经学过的东西:at least once。

在 MQTT 协议中,给出了三种传递消息时能够提供的服务质量标准,这三种服务质量从低到高依次是:

  • At most once: 至多一次。消息在传递时,最多会被送达一次。换一个说法就是,没什么消息可靠性保证,允许丢消息。一般都是一些对消息可靠性要求不太高的监控场景使用,比如每分钟上报一次机房温度数据,可以接受数据少量丢失。

  • At least once:至少一次。消息在传递时,至少会被送达一次。也就是说,不允许丢消息,但是允许有少量重复消息出现。

  • Exactly once:恰好一次。消息在传递时,只会被送达一次,不允许丢失也不允许重复,这个是最高的等级

同时,在“消息幂等”部分,也特别进行了强调:

https://help.aliyun.com/document_detail/146983.html

图片

为了防止消息重复消费导致业务处理异常,有必要根据业务上的唯一 Key 对消息做幂等处理。

虽然我用的这个玩意是一个冷门的 MQ ,但是这个问题和具体使用的哪个 MQ 关系不大,常见的 RabbitM、RocketMQ、Kafka 都有类似的问题,都需要消费端做好幂等处理。

本文就基于这个问题,来讨论一下,在“消息可能重复消费”这个场景下,有没有啥好的解决方案。

举个例子

前面说了,要处理消息重复消费的场景,最核心的逻辑是需要实现幂等机制。

幂等,这个概念大家应该是比较清晰了。

举个具体的例子。

比如在支付场景下,消费者消费扣款消息,对一笔订单执行扣款操作,扣款金额为 100 元。

如果因各种原因导致扣款消息重复投递,比如简单的一个场景,消费者接受到“扣款金额为 100 元”这个信息,完成消费,还没来得及告诉 MQ,“老哥,这个消息我已经收到了”,就重启了。

站在 MQ 的角度,没有收到回执,就代表这个消息并没有消费成功,基于“必须保证消息不丢失的指导思想”,它就会继续投递。

所以消费者会重复消费这个扣款消息。

但是,最终的业务结果是只扣款一次,扣费 100 元,且用户的扣款记录中对应的订单只有一条扣款流水,不会多次扣除费用。

那么这次扣款操作是符合要求的,整个消费过程实现了消费幂等。

在要求幂等的场景中,我们要找到一个抓手。

图片

比如在这个案例里面,扣款一般来说都会对应一个业务上的唯一流水号,这个业务上的唯一流水号,就是抓手,我们可以基于这个流水号来做幂等。

最常规的方案就是在这个字段上加唯一索引,然后出现重复投递时,落库的时候会抛出主键冲突的异常。

不要觉得重复投递是一个小概率事件,就不上心了。我们敲代码的,不就是要多考虑这些正常流程之外的“小概率事件”吗,只写正常流程,谁都会写。

根据官方的说法,消息重复会发生在这些场景中:

  • 发送时消息重复。当一条消息已被成功发送到服务端并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端应答失败。如果此时生产者意识到消息发送失败并尝试再次发送消息,消费者后续会收到两条内容相同并且 Message ID 也相同的消息。

  • 投递时消息重复消息消费的场景下,消息已投递到消费者并完成业务处理,当客户端给服务端反馈应答的时候网络闪断。为了保证消息至少被消费一次,消息队列的服务端将在网络恢复后再次尝试投递之前已被处理过的消息,消费者后续会收到两条内容相同并且 Message ID 也会收到相同的消息。

  • 负载均衡时消息重复(包括但不限于网络抖动、Broker 重启以及消费者应用重启)。当消息队列的 Broker 或客户端重启、扩容或缩容时,会触发 Rebalance,此时消费者可能会收到重复消息。

搞搞具体方案

还是顺着前面扣款的例子说。

收到消息之后,我们第一步一般来说是保存信息到数据库。

save(扣款信息);

现在我们要做幂等,已经找到了扣款唯一流水号这个抓手,那我们的代码应该怎么写呢?

扣款信息 = select(扣款唯一流水号);
if(扣款信息 == null){
    save(扣款信息);
}

先查询,再判断,最后保存。

这个方案,在一般的情况下,能达到幂等的效果。

但是,由于是三步,在并发场景下,立马就扛不住了。

而且,消息重复投递的场景,本来就是在极短的时间内产生的两条信息。

所以,上面这个方案会出现什么场景呢?

两个请求,在 select(扣款唯一流水号) 的时候都没有查询到数据,击穿了校验逻辑,然后两个请求就都会去落库。

这个时候怎么办呢?

很简单,前面说了,在扣款唯一流水号上加唯一索引,即使两个请求都去落库,但是由于有唯一索引,一定只会落一笔数据到数据库。

另外一个怎么办?

抛出唯一索引冲突的异常,在程序里面通过捕获这个异常来控制流程上的后续运转。

这个方案,很常见,很常用,实话实说我们用的就是这个方案。

但是既然已经有唯一索引了,那是不是前面的 select 都显得没啥卵用了?

我们要从辩证的角度去看待这个问题。

所以,是,也不是。

图片

是的原因是因为前面这一层 select 相当于过滤层,能在一些非并发的场景下让程序不抛出唯一索引冲突的异常,显得更加优雅。

不是的原因是因为优雅的程度还不够高,毕竟是通过“异常”来控制了程序的走向。

有没有不抛出异常的方案呢?

也有,也很简单,上锁就行了:

扣款信息 = select(扣款唯一流水号);//select *** for update

这样确实能保证不抛出唯一索引冲突的异常,但是关键是一旦涉及到上锁,性能就拉胯了,为了解决这个偶发的问题,牺牲了接口的性能,这个路线就走的有点远了。

所以,上锁也不够优雅。

什么是真正的优雅?

图片

我也不知道,但是我试图去思考一个相对优雅的方案。

思考一波

首先,我觉得上面的方案,不管是唯一索引,还是上锁,不够优雅的原因是因为,它们都是在基于业务表搞事情。

业务表干得事儿,应该就是业务上的事儿。

那我问你:消息重复投递,需要保持幂等,这个属于业务上的事儿吗?

我认为是不属于的,这是属于技术上的事情,任何业务都是可能遇到的。只不过,在前面的方案里面,我们想借用业务表的能力,来帮我们做一个它可以做,但是本来不该它做的事情。

首先,我们必须要在这一点上达成一致,不然后面的论述就不能展开了。

如果你不这样认为,那么你可以不用往下看。

图片

我想到的方案是什么呢?

我相信你听过这样一句话:计算机领域中的所有问题都可以通过增加一个中间层来解决。

所以,我也想着抽一层。

我还是需要数据库通过唯一索引来帮我保证只有一条数据被成功落库,所以我想着抽一个专门的表出来,比如叫做消息消费记录表。

只要数据插入了这个表,就代表消息被消费了。后续即使重发,也不会插入成功。

那么怎么来保证这个机制呢?

前面提到的抓手又可以用上了:业务唯一流水号。

这个消息消费记录表里面最重要的一个字段,可以叫做“消息唯一标识”,并且作为唯一索引。

这里的这个“消息唯一标识”就是对应业务唯一流水号。

如果你要基于这个表来实现消息幂等,那么你必须具备这样的一个业务唯一流水号,当重复的时候,还是会抛出主键冲突异常。

我知道着听起来就像是脱裤子放屁。

但是,你想想,这个表是完全脱离于业务的存在。

在前面的解决方案中,你要问别人,你有没有一张业务表来做这个事情。

在现在的方案中,你会给别人说,我这里有一个解决方案,你只需要执行我给你的 SQL,生成一张消息消费记录表就行。

这张表是完全独立于业务的存在,它只是为了解决消息重复投递这个共性问题。

从你问别人要,到别人按照你说的做,就这么轻轻的抽一小层,攻守易形了啊,朋友。

它是一种通用的解决方案,一种策略,甚至可以叫做一个框架。

现在,我们可以给它取一个新的名字。

比如:一种基于数据库唯一索引实现消息幂等的解决方案。

或者:一种分布式系统中数据唯一性的保障策略。

再或者:一个由数据库约束驱动的消息幂等保护性框架。

好,现在我们有了这么一个“高大上”的通用解决方案了。

到底怎么用呢?

名字很厉害,但是用起来其实也就那么回事儿。

回到前面转账的例子,很简单:

if(保存数据到消息消费记录表){//出现主键冲突就返回false
    save(扣款信息);    
}

这样,消息防重,由消息消费记录表来保证。

业务表,不感知“消息是否重复”的场景。

看起来似乎是优雅了那么一点点。

但是,同时带来了另外一个问题。

又回到了之前“先校验,再保持”的非原子性的逻辑。

我们想想一个极端场景,如果保存数据到消息消费记录表成功,还没来得及 save(扣款信息) ,服务重启了,怎么办?

其实换句话说,这两个信息需要保持一致性。

所以可以加入事务嘛,把这两步绑定到一起:

开启事务;
if(保存数据到消息消费记录表){//出现主键冲突就返回false
    save(扣款信息);    
}
提交事务;

这样,如果保存数据到消息消费记录表成功,还没来得及 save(扣款信息) ,服务重启,事务回滚,消息消费记录表就不会真的插入成功。

而 MQ 没有收到这个消息的回执,也会再次进行投递。

由于消息消费记录表里没有这个数据,所以会再次进行消费。

在上面的这个过程中,MQ 再次投递,是为了 at least once。

而我们引入了消息消费记录表,通过唯一索引来保证不重复消费,这个玩意加上 at least once,在业界有另外一个叫法:exactly-only。

现在,我们通过引入事务来解决了“非原子性”的问题,但是又带来另外一个问题:事务。

一般来说,大家都是能不使用事务的地方就尽量不使用事务,通过最终一致性来保证数据的完整性。

那现在有没有不基于事务的解决方案呢?

我想到的是可以在消息消费记录表里面再引入一个“状态字段”,这个字段有三个取值:未消费、消费中、消费完成。

通过维护状态的流转,来代替事务的逻辑。

这个思路来源于我实习的时候,给老师做外包项目。当时我是真的不知道 Spring 的事务怎么用,但是我知道结合当时我开发的业务场景,一个数据的状态很重要,处理之前把数据的状态修改了,但是如果出了异常,应该把状态给它恢复回去。

于是我手动写了这样的一坨代码,四处散落在我写的模块里面。

后来一个师兄看了我的代码,提出了应该用事务来保证这样的逻辑,并给我做了演示,我才去了解了事务相关的东西。

但是有一说一,我后来也思考了,在我那个特定的业务场景下,通过状态的流转,确实是可以代替事务的存在的。

好,回到我们现在的这个场景中。

一个消息过来的时候,首先根据唯一消息标识获取对应的数据。

如果没有获取到,就初始化为“未消费”状态落库,然后去执行具体的业务逻辑。在业务逻辑执行之前,把状态修改为“消费中”,然后在执行完成之后,把状态修改为“消费完成”。

如果这个消息被重新投递了,那么根据唯一消息标识就能获取到对应的数据,接着检查这个消息的状态。如果是“消费完成”,直接就丢掉。

但是上面的描述只是描述了最简单的场景,一些复杂场景下状态的流转和判断应该怎么做,我确实还没想好。

所以就当是个课后习题吧,你去推一推,看看用状态流转代替事务的方式是否能成功落地。

学会了记得回来教我。

FlinkKafkaProducer采用EXACTLY_ONCE异常 使用Flink提供的 FlinkKafkaProducer 写入kafka数据的时候,相同的代码相同的环境下,Semantic.AT_LEAST_ONCE 策略一切正常,但是当切换到 Semantic.EXACTLY_ONCE 时,flink作业异常如下: org.apache.kafka.common.KafkaException: Unexpected error in InitProducerIdResponse; The transaction timeout is larger than the 阅读详情

相关推荐

【Flink】Flink 实现 AT_LEAST_ONCE & EXACTLY_ONCE 案例

1.概述 本博客是 Apache Flink 知其然,知其所以然(原理&实战) 的笔记。 @Test public void main1() throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); env.enableCheckpointin.

九师兄 554

Kafka学习笔记

官网httpKafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。消息中间件1.天生分布式2.存储数据3.流处理(聚合、统计)...

m0_52712579的博客 840

在不同版本Python中安装PyQT5及PyQT5-Tools

在不同版本Python中安装PyQT5及PyQT5-Tools

zoomgu680的博客 2万+

RocketMQ消息至少一次(At least Once)投递和消费

至少一次(At least Once)指每个消息必须投递一次。Consumer先Pull消息到本地,消费完成后,才向服务器返回ack,如果没有消费一定不会ack消息,所以RocketMQ可以很好的支持此特性。 生产者 在同步非顺序投递的时候,每次都是轮询到不同的队列: Message message = new Message("topic_family", (" 同...

昕友软件博客 4039

Notion卡顿救星:3分钟搞定DNS优化,手机电脑全平台加速指南

本文针对Notion访问慢和卡顿问题,提供了全平台DNS优化与Hosts文件修改的详细指南。通过更换优质DNS服务器或建立静态IP映射,可有效解决因网络延迟和域名解析导致的加载缓慢,实现手机与电脑端的快速加速,提升Notion使用流畅度。

v6b7n8m9q0的博客 1306

《【一看就会】Autoware.universe的“规划”部分源码梳理》系列文章目录(持续更新中)

第零章:Planning综述 第一章:【一】全局路径生成模块——mission_planner 第二章:【二】路径行为规划模块——behavior_path_planner第一部分——behavior_path_planner模块 第三章:【二】路径行为规划模块——behavior_path_planner第二部分——behavior_path_planner_common模块(1) 第四章:【二】路径行为规划模块——behavior_path_planner第三部分——behavior_path_plan

weixin_48386130的博客 2340

Kafka 接收消息 at least once

– Start 首先启动 ZooKeeper 和 Kafka borker。 下面的例子演示了如何接收数据以及手动提交 offset。 package shangbo.kafka.example5; import java.util.Arrays; import java.util.Properties; import org.apache.kafka.clients.consum...

千里之行始于足下 5709

【麒麟桌面系统】企业微信提示当前副设备的企业微信版本较低

银河麒麟系统中登录企业微信时出现"副设备版本较低"的报错,可通过两种方案解决:1)更新最新版企业微信,需替换软件源并刷新软件商店安装8.0-50-4.1.26.6019kylin5版本;2)安装内测5.0版本企业微信,需下载deb包后使用sudo dpkg命令安装。文章还提供了常见问题解决表和长期维护建议,包括系统更新检查、软件源验证等维护项目及具体操作指南。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 2276

哎-被这个叫做at-least-once的玩意坑麻了

执行转账操作; } 这个方案,适用于**所有**业务场景了。 ### 方案四:Redis 既然数据库可以搞,那么 Redis 是不是也可以搞? 当然可以搞。 而且 Redis 的性能更好,更轻量。 比如这样: > `SET 消息唯一标识 1 EX 30 NX` 如果设置成功了,就代表消息没有被消费过,可以执行业务逻辑。 如果设置失败了,就代表消息已经被消费了,直接返回即可。 ### 方案五:布隆过滤器 Redis 都搞了,那么布隆过滤器是不是也可以搞? 布隆过滤器虽然有一定的误判率,但是在幂等这个场景下,误

Java程序员的知识博客 254

【数字孪生与仿真技术】06:航天器系统建模与验证全流程实战:从多学科建模到数字孪生(附完整代码与工业案例)

摘要:航天器系统开发面临多学科耦合强、验证流程复杂、可靠性要求极高的挑战。本文基于MATLAB/Simulink平台,系统阐述航天器从多域建模、动力系统开发到任务验证的全流程技术框架。内容涵盖Modelica统一建模规范、光伏-电池联合供电系统仿真、基于模型的需求追溯方法、蒙特卡洛可靠性分析及硬件在环测试等核心技术,并结合James Webb太空望远镜电力系统案例,展示工业级应用实践。文中提供完整的Simulink模型代码、仿真结果及流程图,最后探讨数字孪生与AI增强技术在航天器在轨运维中的未来应用。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1373

【部署】Docker部署OpenClaw及常见问题解决(win11)

给AI单独开一个隔离的小容器,AI执行所有命令、下载文件都在这个小盒子里,就算AI被诱导执行危险命令,也不会影响你Win11本机的文件和系统,是必开的安全功能。Docker容器里的OAuth回调,会尝试在你Win11本机的1455端口捕获认证信息,但容器和Win11本机的网络隔离,导致浏览器访问不到这个回调地址。「挂载」就是把你Win11本机的文件夹,共享给容器里的「虚拟小电脑」,两边都能读写文件,比如你想让AI操作你D盘里的代码文件,就需要挂载。

海兰 4699

Flink的CheckPoint(EXACTLY_ONCE,AT_LEAST_ONCE)

消息语义概述, 在分布式系统中,构成系统的任何节点都是被定义为可以彼此独立失败的。比如在 Kafka中,broker可能会crash,在producer推送数据至topic的过程中也可能会遇到网络问题。根据producer处理此类故障所采取的提交策略类型,我们可以获得不同的语义: at-most-once:如果在ack超时或返回错误时producer不重试,则该消息可能最终不会写入Kafka,...

长乐的博客 4270

C#实现低通和高通滤波算法

低通滤波器允许通过低于某个截止频率的信号成分,并且抑制高于该频率的成分。而高通滤波器则允许通过高于某个截止频率的信号成分,并抑制低于该频率的成分。巴特沃斯滤波器是一种对称的滤波器,具有平坦的幅度响应和最小的群延迟。低通和高通滤波是数字信号处理中常用的滤波技术,用于滤除或增强信号中的特定频率成分。在本篇文章中,我们将使用C#编程语言来实现低通和高通滤波算法。以上就是使用C#实现低通和高通滤波算法的示例代码。你可以根据自己的需求调整截止频率和采样率,将这些代码应用于你的项目中。是滤波器的截止频率,

XisVisual_Basic的博客 1275

Kafka - 消息投递语义:At-Least-Once、At-Most-Once、Exactly-Once实现

Kafka消息投递语义解析 本文深入探讨Kafka的三种消息投递语义:At-Most-Once(至多一次)、At-Least-Once(至少一次)和Exactly-Once(恰好一次)。通过对比分析三种语义的特点、实现原理及适用场景,帮助开发者构建可靠的数据管道。 核心要点 At-Most-Once:速度优先,可能丢失消息但不会重复 实现方式:Producer设置acks=0,Consumer预提交偏移量 适用场景:可容忍丢失的日志收集和监控数据 At-Least-Once:可靠性优先,保证不丢失但可能重复

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

【100%通过率】2023华为od机试C卷【电脑病毒感染】Java&Go 实现

一个局域网内有很多台电脑,分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用t 表示。其中网络内一台电脑被病毒感染,求其感染网络内所有的电脑最少需要多长时间。如果最后有电脑不会感染,则返回-1.

MISAYAONE的博客 2863

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

全面剖析Flink CheckPoint机制与Exactly Once和At Least Once语义

看完本文,你能 get 到以下知识: 介绍 CheckPoint 如何保障 Flink 任务的高可用 CheckPoint 中的状态简介 如何实现全域一致的分布式快照? 什么是 barrier?什么是 barrier 对齐? 证明了:为什么 barrier 对齐就是 Exactly Once,为什么 barrier 不对齐就是 At Least Once。 Flink 简介 有状态函数和运算符...

探索大数据世界 - 深入解析数据存储、分布式计算与人工智能 5469

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

RPC:at-most-once vs at-least-once

RPC(Remote Procedure Call)是分布式系统机制的重要部分,被广泛使用 RPC消息传输: RPC的软件结构: RPC中 Client 可能会出现的 failure: Client 没有收到 Server 的回应 Client 不知道 Server 是否收到了 Request(或许 Server/Net 在发送回复的时候失败了) 最简单的解决 failu...

sdoddyjm68的博客 4173

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Storm At-Least-Once 语义深度解析:如何保证消息不丢失

在分布式流处理系统中,消息的可靠性是一个核心问题。(最多一次)、(至少一次)和(精确一次)。其中,At-Least-Once 是最常用的一种语义,它保证了消息不会丢失,但可能重复处理。本文将深入剖析 Storm 如何通过 Spout、Bolt 和 Acker 的协同工作,实现 At-Least-Once 处理语义,并通过流程图和代码示例帮助读者彻底理解这一机制。At-Least-Once(至少一次)每条从 Spout 发出的消息,都会被确保处理至少一次。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 3013

终极指南:Disque分布式消息投递语义详解——At-Least-Once与At-Most-Once实现原理

Disque作为一款高性能分布式消息代理,其核心价值在于可靠的消息投递机制。本文将深入解析Disque如何实现两种关键消息投递语义——At-Least-Once(至少一次)和At-Most-Once(最多一次),帮助开发者理解其内部工作原理并正确配置消息投递策略。 ## 📌 消息投递语义基础:为什么它如此重要? 在分布式系统中,消息投递语义直接影响业务数据一致性和系统可靠性。Disque通过

gitblog_01080的博客 872

Flink 的 Exactly Once 和 At Least Once

exactly-once:即使producer重试发送消息,消息也会保证最多一次地传递给最终consumer。该语义是最理想的,但也难以实现,这是因为它需要消息系统本身与生产和消费消息的应用程序进行协作。例如如果在消费消息成功后,将Kafka consumer的偏移量rollback,我们将会再次从该偏移量开始接收消息。这表明消息传递系统和客户端应用程序必须配合调整才能实现excactly-once at-least-once:如果producer收到来自Kafka broker的确认(ack)或者ack

jia_yp的博客 2252

消息系统可靠性保障深度解析:从at-most-once到exactly-once的渐进演进路径

消息系统三种交付语义的代价递增:at-most-once无ACK机制吞吐最高但可丢消息(适用日志/指标),at-least-once通过Producer重传+Consumer手动ACK保证不丢但可能重复(重复率0.1%-1%),exactly-once需要Producer幂等(PID+SeqNum Broker端去重)+Consumer幂等(去重表查询10-50ms)实现零丢零重复但吞吐下降30%-50%。

jiang_style的博客 4246

Apache Kafka 3.1消息投递语义:At-Least-Once实现原理

在分布式系统中,消息投递语义(Message Delivery Semantics)定义了消息从生产者到消费者的可靠传递保证。Kafka支持三种典型语义: - **At-Most-Once(最多一次)**:消息可能丢失,但不会重复 - **At-Least-Once(至少一次)**:消息不会丢失,但可能重复 - **Exactly-Once(恰好一次)**:消息精确传递一次,不丢失不重复 本文聚...

gitblog_00147的博客 688

ZoneMTA 架构深度解析:Master/Child 进程模型与 at-least-once 投递机制

ZoneMTA 是一款基于 Node.js 和 MongoDB 构建的现代开源出站邮件中继(Outbound MTA),它采用独特的 **Master/Child 进程模型**来组织运行时架构,并通过 MongoDB 队列实现了可靠的 **at-least-once 投递**语义。本文将从源码层面深入剖析 ZoneMTA 的多进程设计思路,解释它如何同时做到高吞吐、高可用与消息不丢失,帮助你真正理

gitblog_00107的博客 660

【Kafka源码解读和使用指南】第24篇:消息传递保证语义深度解析——at-most-once/at-least-once/exactly-once

消息传递保证语义深度解析 本文详解Kafka三种消息传递语义:at-most-once(最多一次,可能丢消息)、at-least-once(至少一次,可能重复)、exactly-once(精确一次)。通过ASCII图解展示故障场景,分析Producer和Consumer端的关键配置实现方式,并给出各语义的适用场景建议。at-most-once适用于可容忍丢失的日志场景,at-least-once适用于可去重的业务场景,exactly-once则通过Kafka 0.11引入的事务机制实现端到端的精确一次处理,

xyghehehehe的专栏 196

storm是如何保证at least once语义的

storm是通过什么机制来保证消息至少处理一次的语义的

浩然之气,兼容并蓄 http://blog.youkuaiyun.com/gsky1986 6522

Flink exactly-once 实战笔记(精确一次写入外部数据)

Flink-Kafka 众所周知,Flink在很早的时候就通过Checkpointing提供了exactly-once的semantic,不过仅限于自身或者是从KafkaConsumer中消费数据。而在Flink 1.4版本的时候加入了赫赫有名的TwoPhaseCommitSinkFunction,提供了End-to-End的exatcly-once语言,当然是在需要下游支持回滚的情况下,具体的...

hellojoy的博客 1955
上一篇: 周鸿祎AI产品翻车事件始末,被群嘲后又惹上官司!被盗图者:我要的是公开道歉和1元RMB赔偿!
下一篇: 全中国熬夜看欧洲杯的球迷,都被这个东西硬控了两分钟。
IT界那些事儿
博客等级 码龄6年 2万+粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值