rocketmq怎么保证数据不会重复_RocketMQ保证信息有序性和防止重复

分布式开放消息系统(RocketMQ)的原理与实践

分布式消息系统做为实现分布式系统可扩展、可伸缩性的关键组件,须要具备高吞吐量、高可用等特色。而谈到消息系统的设计,就回避不了两个问题:java

消息的顺序问题

消息的重复问题

RocketMQ做为阿里开源的一款高性能、高吞吐量的消息中间件,它是怎样来解决这两个问题的?RocketMQ 有哪些关键特性?其实现原理是怎样的?web

关键特性以及其实现原理

1、顺序消息

消息有序指的是一类消息消费时,能按照发送的顺序来消费。例如:一个订单产生了 3 条消息,分别是订单建立、订单付款、订单完成。消费时,要按照这个顺序消费才有意义。但同时订单之间又是能够并行消费的。算法

假如生产者产生了2条消息:M一、M2,要保证这两条消息的顺序,应该怎样作?你脑中想到的多是这样:服务器

a545172a49a04e6e9b5fb85c.html

你可能会采用这种方式保证消息顺序网络

M1发送到S1后,M2发送到S2,若是要保证M1先于M2被消费,那么须要M1到达消费端后,通知S2,而后S2再将M2发送到消费端。负载均衡

这个模型存在的问题是,若是M1和M2分别发送到两台Server上,就不能保证M1先达到,也就不能保证M1被先消费,那么就须要在MQ Server集群维护消息的顺序。那么如何解决?一种简单的方式就是将M一、M2发送到同一个Server上:分布式

a545172a49a04e6e9b5fb85c.html

保证消息顺序,你改进后的方法ide

这样能够保证M1先于M2到达MQServer(客户端等待M1成功后再发送M2),根据先达到先被消费的原则,M1会先于M2被消费,这样就保证了消息的顺序。svg

这个模型,理论上能够保证消息的顺序,但在实际运用中你应该会遇到下面的问题:性能

a545172a49a04e6e9b5fb85c.html

网络延迟问题

只要将消息从一台服务器发往另外一台服务器,就会存在网络延迟问题。如上图所示,若是发送M1耗时大于发送M2的耗时,那么M2就先被消费,仍然不能保证消息的顺序。即便M1和M2同时到达消费端,因为不清楚消费端1和消费端2的负载状况,仍然有可能出现M2先于M1被消费。如何解决这个问题?将M1和M2发往同一个消费者便可,且发送M1后,须要消费端响应成功后才能发送M2。

但又会引入另一个问题,若是发送M1后,消费端1没有响应,那是继续发送M2呢,仍是从新发送M1?通常为了保证消息必定被消费,确定会选择重发M1到另一个消费端2,就以下图所示。

a545172a49a04e6e9b5fb85c.html

保证消息顺序的正确姿式

这样的模型就严格保证消息的顺序,细心的你仍然会发现问题,消费端1没有响应Server时有两种状况,一种是M1确实没有到达,另一种状况是消费端1已经响应,可是Server端没有收到。若是是第二种状况,重发M1,就会形成M1被重复消费。也就是咱们后面要说的第二个问题,消息重复问题。

回过头来看消息顺序问题,严格的顺序消息很是容易理解,并且处理问题也比较容易,要实现严格的顺序消息,简单且可行的办法就是:

保证生产者 - MQServer - 消费者是一对一对一的关系

可是这样设计,并行度就成为了消息系统的瓶颈(吞吐量不够),也会致使更多的异常处理,好比:只要消费端出现问题,就会致使整个处理流程阻塞,咱们不得不花费更多的精力来解决阻塞的问题。

但咱们的最终目标是要集群的高容错性和高吞吐量。这彷佛是一对不可调和的矛盾,那么阿里是如何解决的?

世界上解决一个计算机问题最简单的方法:“刚好”不须要解决它!

有些问题,看起来很重要,但实际上咱们能够经过合理的设计或者将问题分解来规避。若是硬要把时间花在解决它们身上,其实是浪费的,效率低下的。从这个角度来看消息的顺序问题,咱们能够得出两个结论:

一、不关注乱序的应用实际大量存在

二、队列无序并不意味着消息无序

最后咱们从源码角度分析RocketMQ怎么实现发送顺序消息。

通常消息是经过轮询全部队列来发送的(负载均衡策略),顺序消息能够根据业务,好比说订单号相同的消息发送到同一个队列。下面的示例中,OrderId相同的消息,会发送到同一个队列:

// RocketMQ默认提供了两种MessageQueueSelector实现:随机/Hash

SendResult sendResult = producer.send(msg, new MessageQueueSelector() {

@Override

public MessageQueue select(List mqs, Message msg, Object arg) {

Integer id = (Integer) arg;

int index = id % mqs.size();

return mqs.get(index);

}

}, orderId);

在获取到路由信息之后,会根据MessageQueueSelector实现的算法来选择一个队列,同一个OrderId获取到的队列是同一个队列。

private SendResult send() {

// 获取topic路由信息

TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());

if (topicPublishInfo != null && topicPublishInfo.ok()) {

MessageQueue mq = null;

// 根据咱们的算法,选择一个发送队列

// 这里的arg = orderId

mq = selector.select(topicPublishInfo.getMessageQueueList(), msg, arg);

if (mq != null) {

return this.sendKernelImpl(msg, mq, communicationMode, sendCallback, timeout);

}

}

}

2、消息重复

上面在解决消息顺序问题时,引入了一个新的问题,就是消息重复。那么RocketMQ是怎样解决消息重复的问题呢?仍是“刚好”不解决。

形成消息的重复的根本缘由是:网络不可达。只要经过网络交换数据,就没法避免这个问题。因此解决这个问题的办法就是不解决,转而绕过这个问题。那么问题就变成了:若是消费端收到两条同样的消息,应该怎样处理?

一、消费端处理消息的业务逻辑保持幂等性

二、保证每条消息都有惟一编号且保证消息处理成功与去重表的日志同时出现

第1条很好理解,只要保持幂等性,无论来多少条重复消息,最后处理的结果都同样。第2条原理就是利用一张日志表来记录已经处理成功的消息的ID,若是新到的消息ID已经在日志表中,那么就再也不处理这条消息。

咱们能够看到第1条的解决方式,很明显应该在消费端实现,不属于消息系统要实现的功能。第2条能够消息系统实现,也能够业务端实现。正常状况下出现重复消息的几率不必定大,且由消息系统实现的话,确定会对消息系统的吞吐量和高可用有影响,因此最好仍是由业务端本身处理消息重复的问题,这也是RocketMQ不解决消息重复的问题的缘由。

RocketMQ不保证消息不重复,若是你的业务须要保证严格的不重复消息,须要你本身在业务端去重。

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

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

相关文章

云效Codeup代码评审中的代码协同

简介: 云效 Codeup 汇集了阿里巴巴最新的代码托管、代码协同技术,希望能够造福更多中国和世界的开发者。 大神说:“Show me the code”,于是就有了代码评审。 “Talk is cheap. Show me the code.” ——Linus Torvalds, founder …

代码安全无忧—云效Codeup代码加密技术发展之路

简介: 从代码服务及代码安全角度出发,看看云效代码加密技术如何解决这一问题 代码数据存在云端,如何保障它的安全? 部分企业管理者对于云端代码托管存在一丝担心:我的代码存在云端服务器,会不会被泄露&…

杀死 Oculus ,Facebook 改名 Meta ,是押注元宇宙还是“金蝉脱壳”?

整理 | 祝涛出品 | CSDN(ID:CSDNnews)美东时间10月28日周四,在名为Facebook Connect的年度大会上,Facebook宣布,Facebook将公司名称更改为“Meta”,这个新名字反映了该公司在社交媒体之外的雄心…

java sdp_[java,SDP] java 7 SDP 技术/Socket Direct Protocol 2

With Java 7 and Sockets Direct Protocol , Java Now does RDMA ( Remote Direct Memory Access)有了 SDP 技术支持之后的 Java 7 已经开始逐步实现 RDMA 技术 (远程内存直接访问)RDMA is Remote Dynamic Memory Accesss -- which is a way of moving application buffers bet…

百信银行基于 Apache Hudi 实时数据湖演进方案

简介: 本文介绍了百信银行实时计算平台的建设情况,实时数据湖构建在 Hudi 上的方案和实践方法,以及实时计算平台集成 Hudi 和使用 Hudi 的方式。 本文介绍了百信银行实时计算平台的建设情况,实时数据湖构建在 Hudi 上的方案和实践…

如何做一场高质量的分享

简介: 每个人在分享前都应该先问自己这么一个问题,我为什么要分享?我觉得分享就一个最纯粹的原因,就是“我有一些知识,是别人不知道的,但对他人会有所帮助,所以我想分享给大家”。 作者 | 阿相 …

RTE2021,实时互动技术的进化与蝶变

10 月 22—23 日,由声网 Agora 主办的 RTE2021 实时互联网大会在北京圆满落幕。大会以“万象频道”为主题,带来了 20 余场实时互联网全生态线下论坛及活动、近百场的精彩演讲分享,覆盖技术开发、行业观察、创业投资、趋势洞察等多维度话题。同…

Java编程技巧之单元测试用例编写流程

简介: 立足于“如何来编写单元测试用例”,让大家“有章可循”,快速编写出单元测试用例。 作者 | 常意 来源 | 阿里技术公众号 温馨提示:本文较长,同学们可收藏后再看 :)前言 清代杰出思想家章学诚有一句名言&#xff…

KubeVela + KEDA:为应用带来“与生俱来”的弹性伸缩能力

简介: 在这篇博文中,我们将简要解释需要考虑的领域,KEDA 如何使应用自动伸缩变得简单,以及为什么阿里云企业分布式应用服务(EDAS)在 KEDA 上完全标准化。 联合作者 | Yan Xun,阿里云 EDAS 团队…

mysql行转列函数_一个小知识点-Hive行转列实现Pivot

前言传统关系型数据库中,无论是Oracle(11g之后)还是SQLserver(2005之后),都自带了Pivot函数实现行转列功能,本文主要讲述在Hive中实现行转列的两种方式。传统数据库方式这种方式是借鉴在Oracle或者SQLserver在支持Pivot函数之前实现行转列的方…

安全之心:一文读懂可信计算

简介: 信 or 不信,这是个问题 可信计算 TC (Trusted Computing) 业界新宠,越来越被高频提到 本质是创造可信执行环境的芯片级安全防护方案 然而,江湖流传 TA 的传说 却鲜少有人见过真身 阿里云作为亚太区最…

国内顶级AI赛事再启程,第三届“中国人工智能大赛”聚焦算法治理、深度伪造与网络安全

本届大赛赛题分为算法治理、深度伪造和网络安全三大方向的七大赛题,分别是:过滤算法鲁棒性、深度伪造视频检测、深度伪造视频生成方法识别、基于人工智能的音视频合成比赛、说话人无关的音频深度伪造检测识别、说话人相关的音频深度伪造检测识别、Webshe…

看阿里云如何用云上技术创新,帮助哈啰单车实现智能数据收治

简介: 客户通过把日志数据迁移到SLS,替代原有的kafka、ES、ClickHouse,累积节省成本达到30%,同时满足了稳定性、扩展性需求,以及对日志查询分析的需求。 更多存储标杆案例 欢迎点击下方链接查看 阿里云存储标杆案例样…

快进键启动,一文带你了解云原生时代容器安全

简介: 分享阿里云容器安全的治理能力与经验,致力保护生产环境安全。 都说国内需求离容器化还远,更谈不上关注安全,喊的热闹而落地困难。但总得有些声音面向未来向前看。 在2020年Forrester IaaS安全评测中,阿里云容器…

Serverless:这真的是未来吗?(一)

简介: 希望这些博客文章能帮助您在所有相关人员中展开讨论,就最佳业务方案达成一致。该课程可能涉及无服务器,也可能不涉及。在这第一篇文章中,我们将考虑在讨论无服务器时最常见的几个问题。在第二篇文章中,我们将研究…

无限级分类限定层级_王者荣耀:s20战令该不该买?战令限定星元皮肤实测真香...

王者荣耀:s20战令该不该买?战令限定星元皮肤实测真香Hello大家好,我是游戏鲪,很高兴见到大家。如今这个赛季的战令系统早已结束,新赛季也即将到来。许多小伙伴都在憧憬下个赛季的战令。关于s20赛季的战令奖励&#xff…

光进铜退下的“更高”与“更低”,锐捷发布企业极简以太全光网解决方案

全新一代企业网络建设中,以太全光网将满足高带宽、简运维、降成本的要求。 头图 | 付费下载于视觉中国 出品 | CSDN云计算 近日,锐捷网络正式对外发布企业极简以太全光网解决方案。方案针对仓储物流、电子信息、工业制造、地产酒店等在行业客户在园区网…

物联网海量时序数据存储有哪些挑战?

简介: 随着 IoT 技术的快速发展,物联网设备产生的数据呈爆炸式增长,数据的总量(Volume)、数据类型越来越多(Variety)、访问速度要求越来越快(Velocity)、对数据价值&…

什么是 RedCap?一文详解!

作者 | 小枣君来源 | 鲜枣课堂随着3GPP R17版本的不断推进,一个新的名词逐渐开始热门起来,那就是RedCap。究竟什么是RedCap?为什么要引入它?它和现在的5G有什么区别?且看本文的深入解析……█ 什么是RedCapRedCap&…

被解救的代码 - 代码即服务时代来了!

简介: 人类对自由的追求从未停止,我们用战斗获得民族自由,我们用代码获得双手自由,同时代码作为服务器的奴隶,也开始蠢蠢欲动,革命已经开始,当代码翻身做主,作为开发者的我们又该如何…