阿里面试:canal+MQ,会有乱序的问题吗?

news2024/9/9 1:15:20

阿里面试:canal+MQ,会有乱序的问题吗?

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

canal+MQ,会有乱序的问题吗?

如何保证RocketMQ消息有序?

最近有小伙伴在面试阿里,又遇到了相关的面试题。

小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V140版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

1、如何保证消息顺序?

如何实现消息有序?实现顺序消息所必要的条件:顺序发送、顺序存储、顺序消费。

在MQ模型中,顺序需由3个阶段去保障

  1. 顺序发送: 发送时保持顺序一致
  2. 顺序存储: broker 存储时保持 顺序一致
  3. 顺序消费: 消费时 保持 顺序一致

2 消息有序的两大类型

有序消息,又叫顺序消息(FIFO消息),指消息的消费顺序和产生顺序相同。

如订单的生成、付款、发货,这串消息必须按序处理。

顺序消息又可分为全局有序和局部有序:

  • 全局有序:整个MQ系统的所有消息严格按照队列先入先出顺序进行消费
  • 局部有序:只保证一部分关键信息的消费顺序

2.1 全局顺序

一个Topic内所有的消息都发布到同一Q,按FIFO顺序进行发布和消费:

落地到RocketMQ,如何保证全局有序?

为了 保证Topic全局消息有序的方式,就是将Topic配置成只有一个唯一的MessageQueue队列, 默认是4个MessageQueue。

RocketMQ中,可以在发送者发送消息时指定一个MessageSelector对象,让这个对象来决定消息发入哪一个MessageQueue。这样就可以保证一组有序的消息能够发到同一个MessageQueue里。

适用场景

性能要求不高,所有消息严格按照FIFO进行消息发布和消费的场景。

2.2 分区顺序

对于指定的一个Topic,所有消息按sharding key进行区块(queue)分区,同一Queue内的消息严格按FIFO发布和消费。

  • Sharding key是顺序消息中用来区分不同分区的关键字段,和普通消息的Key完全不同。

落地到RocketMQ。而MessageQueue是RocketMQ存储消息的最小单元,他们之间的消息都是互相隔离的,在这种情况下,是无法保证消息全局有序的,但是可以保证局部有序。

默认的做法是,发送消息时,会通过MessageQueue轮询的方式保证消息尽量均匀分布到所有的MessageQueue上,而消费者也就同样需要从多个MessageQueue上消费消息。这就做不到局部有序。

对于局部有序的要求,只需要将有序的一组消息都存入同一个MessageQueue里,这样MessageQueue的FIFO设计天生就可以保证这一组消息的有序。

适用场景

性能要求高,根据消息中的sharding key去决定消息发送到哪个queue。

其实大部分的MQ业务场景,我们只需要保证局部有序就可以了。

例如

  • 我们用QQ聊天,只需要保证一个聊天窗口里的消息有序就可以了。

  • 而对于电商订单场景,也只要保证一个订单的所有消息是有序的就可以了。

2.3 对比

发送方式对比

存储方式对比

消费方式对比

  • 有序消费的消费者类型:ConsumeMessageConcurrentlyService 并发消费服务

  • 无序消费的消费者类型:ConsumeMessageOrderlyService

3 应用开发维度的实现消息有序需要做的工作:

实现顺序消息所必要的条件:顺序发送、顺序存储、顺序消费。 顺序存储环节,RocketMQ 里的分区队列 MessageQueue 本身是能保证 FIFO 的。

所以,在应用开发过程中,不能顺序消费消息主要有两个原因:

  • 顺序发送环节,消息发生没有序:Producer 发送消息到 MessageQueue 时是轮询发送的,消息被发送到不同的分区队列,就不能保证 FIFO 了。
  • 顺序消费环节,消息消费无序:Consumer 默认是多线程并发消费同一个 MessageQueue 的,即使消息是顺序到达的,也不能保证消息顺序消费。

我们知道了实现顺序消息所必要的条件:顺序发送、顺序存储、顺序消费。

顺序存储 由 Rocketmq 完成,所以,在应用开发层, 消息的顺序需要由两个阶段保证:

  • 消息发送有序
  • 消息消费有序

在这里插入图片描述

4:canal+MQ,如何实现有序?

Canal 是阿里巴巴开源的一个增量订阅和消费的中间件,用于基于 MySQL 的数据库增量日志解析(Binlog)。通过 Canal,可以实现对数据库的实时监控和数据同步。

我们在通过Canal把MySQL的Binlog数据发送到MQ(kafak/rocketmq)时,需要关注好几个环节:

  • Cannal 的有序监听。 Binlog本身是有序的,写入到mq之后如何保障顺序
  • Cannal 的有序发送。
  • 顺序存储: broker 存储时保持 顺序一致
  • 顺序消费: 消费时 保持 顺序一致

4.1 Cannal 的有序发送

canal目前支持kafka和rocketmq,在使用 Canal 进行数据同步时,保证数据的有序性是一个重要的问题,尤其是在分布式环境中。在 Kafka 或 RocketMQ 等消息队列中,消息的顺序性和分区策略至关重要。

canal 本质上都是基于本地文件的方式来支持分区级别的顺序消息,也就是binlog写入mq是可以有一定的顺序性保障,这个保障级别取决于用户的两个配置项:

  • canal.mq.partitionsNum
  • canal.mq.partitionHash

两个配置项 用于控制消息的分区和顺序。两个配置项介绍如下:

  1. canal.mq.partitionsNum
    • 描述:设置消息队列的分区数量。
    • 作用:决定了消息在消息队列中被分区的数量。不同的分区可以并行处理,但需要注意同一个分区内的消息是有序的。
  2. canal.mq.partitionHash
    • 描述:设置消息分区的哈希规则。
    • 作用:用于指定分区的哈希策略,可以根据特定的字段进行分区。例如,可以根据表名、主键等字段进行分区,以保证某些关键数据的有序性。

4.2 Cannal 的有序发送示例

假设我们希望将数据同步到 Kafka,并且需要保证某张表的数据是有序的,可以使用以下配置:

canal.mq.partitionsNum=10
canal.mq.partitionHash=my_database.my_table:id

配置解释

  1. canal.mq.partitionsNum=10
    • 表示消息会被分成 10 个分区。每个分区可以并行处理,从而提高处理效率。
  2. canal.mq.partitionHash=my_database.my_table
    • 针对 my_database.my_table 表的数据,根据 id 字段进行哈希分区。
    • 这样可以确保同一个 id 的所有变更都进入同一个分区,从而保证该 id 的变更顺序不变。

通过配置 canal.mq.partitionHash,分区内的消息是有序的,因此只要保证同一实体(如同一行数据)的变更进入同一个分区,就能保证其有序性。

4.3 Cannal 的使用场景

  • 实时数据同步:将数据库的变更实时同步到其他系统,如搜索引擎、缓存等。
  • 数据备份:实现数据库的实时备份,确保数据的一致性和完整性。
  • 事件驱动架构:在事件驱动架构中,利用 Canal 将数据库变更作为事件发布到消息队列,供其他系统消费。

通过合理配置 canal.mq.partitionsNumcanal.mq.partitionHash,可以在数据同步中既保证有序性,又提高处理效率。

尼恩《技术自由圈》多个核心MQ面试题

惊呆:RocketMQ顺序消息,是“4把锁”实现的(顺序消费)

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压?

滴滴面试:Rocketmq消息0丢失,如何实现?

得物面试:消息0丢失,Kafka如何实现?

说在最后

至此,Canal+MQ的有序性方案,非常圆满了。

以上的内容,如果大家能烂熟于心、对答如流、如数家珍,基本上 面试官会被你 震惊到、吸引到。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会,可以找尼恩来改简历、做帮扶。

遇到职业难题,找老架构取经, 可以省去太多的折腾,省去太多的弯路。

尼恩指导了大量的小伙伴上岸,前段时间,刚指导一个40岁+被裁小伙伴,拿到了一个年薪100W的offer。

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由”

另外,尼恩也给一线企业提供 《DDD 的架构落地》企业内部培训,目前给不少企业做过内部的咨询和培训,效果非常好。

在这里插入图片描述

尼恩技术圣经系列PDF

  • 《NIO圣经:一次穿透NIO、Selector、Epoll底层原理》
  • 《Docker圣经:大白话说Docker底层原理,6W字实现Docker自由》
  • 《K8S学习圣经:大白话说K8S底层原理,14W字实现K8S自由》
  • 《SpringCloud Alibaba 学习圣经,10万字实现SpringCloud 自由》
  • 《大数据HBase学习圣经:一本书实现HBase学习自由》
  • 《大数据Flink学习圣经:一本书实现大数据Flink自由》
  • 《响应式圣经:10W字,实现Spring响应式编程自由》
  • 《Go学习圣经:Go语言实现高并发CRUD业务开发》

……完整版尼恩技术圣经PDF集群,请找尼恩领取

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

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

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

相关文章

一个 Docker 搭建的自动化电视剧下载和管理工具

大家好,我是CodeQi! 一个标准的“追剧狂人”。每周都有新剧上线,每天都要时刻关注各大影视平台的更新,这无疑是一项体力与脑力并存的艰巨任务。 于是,我决定为自己打造一个自动化的电视剧下载和管理工具。作为一个程序员,用 Docker 搭建这种自动化工具简直是小菜一碟。…

Vue组件通信props和$emit用法

父传子&#xff0c;通过props 子传父&#xff0c;通过$emit App.vue <template><div class"app" style"border: 3px solid #000; margin: 10px">我是APP组件<!-- 1.给组件标签&#xff0c;添加属性方式 赋值 --><!-- 添加属性传值 …

PointCloudLib GridMinimum获取栅格最低点 C++版本

测试效果 简介 在点云库(Point Cloud Library, PCL)中,如果你想要获取一个栅格(Grid)内的最低点,这通常意味着你需要先对点云数据进行某种形式的栅格化处理,然后在每个栅格内寻找最低的点。 测试代码 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointC…

2024透明加密软件最新推荐丨11款好用的透明加密软件

在数字化时代&#xff0c;文件与数据安全愈发重要&#xff0c;保护信息安全刻不容缓。文件加密软件应运而生&#xff0c;成为了信息安全的重要帮手。透明加密技术凭借众多的优点备受青睐。那么&#xff0c;什么是透明加密技术呢&#xff1f; 透明加密技术是一种在不影响用户正…

旷野之间11 - 开源 SORA 已问世!训练您自己的 SORA 模型!

​​​​​ 目前最接近 SORA 的开源模型是 Latte,它采用了与 SORA 相同的 Vision Transformer 架构。Vision Transformer 究竟有何独特之处?它与之前的方法有何不同? Latte 尚未开源其文本转视频训练代码。我们复制了论文中的文本转视频训练代码,并将其提供给任何人使用,…

帕金森小伙伴必看!这些维生素让你的生活更“稳“定!

&#x1f308; 嗨&#xff0c;亲爱的小伙伴们&#xff01;今天来跟大家聊聊帕金森病患者应该补充哪些维生素的小知识&#xff0c;让我们的身体更健康&#xff0c;生活更美好哦&#xff01;&#x1f609; &#x1f34e; 维生素C 你知道吗&#xff1f;维生素C不仅能让我们的皮肤…

【Linux】内核文件系统系统调用流程摸索

内核层可以看到当前调用文件处理的进程ID 这个数据结构是非常大的&#xff1a; 我们打印的pid,tgid就是从这里来的&#xff0c;然后只需要找到pid_t的数据类型就好了。 下图这是运行的日志信息&#xff1a; 从上述日志&#xff0c;其实我也把write的系统调用加了入口的打印信…

ADS基础教程24 - Gerber文件的导入

EM介绍 一、引言二、基本概念1.仿真文件下载2.仿真文件介绍 二、导入步骤1.新建workspace2.选择Layout结构3.导入设计4.选择文件类型5.导入文件6.预览文件内容7.铜皮离散问题 四、总结 一、引言 本章节开始介绍在ADS中进行PCB仿真&#xff0c;首先讲解如何将Gerber文件导入到A…

Spark RDD优化

Spark RDD优化 一、分区优化二、持久化优化三、依赖优化四、共享变量优化五、提交模式与运行模式优化六、其他优化 一、分区优化 分区数调整&#xff1a;RDD的分区数可以通过repartition和coalesce方法进行调整。合理的分区数可以提高并行度&#xff0c;但过多的分区会增加管…

2024年Wolf沃尔夫奖数学奖得主出炉:诺加·阿隆(Noga Alon)、阿迪·萨莫尔(Adi Shamir)

沃尔夫基金会官网&#xff1a;2024年沃尔夫数学奖联合颁发给了以色列魏茨曼科学研究所的阿迪萨莫尔 &#xff08;Adi Shamir&#xff0c;1952 -&#xff09; 教授和美国普林斯顿大学的诺加阿隆&#xff08;Noga Alon&#xff0c;1963 -&#xff09; 教授&#xff0c;表彰他们对…

ADI新型充电器解决方案可实现电池堆电压和充电效率

就目前而言&#xff0c;这可能是生活中zui常见的问题了。世纪之交&#xff0c;电池&#xff08;尤其是基于锂离子的电池&#xff09;成本的降低和性能的提高&#xff0c;推动了电池供电的储能和便携式设备的稳步增长。此外&#xff0c;超级电容器由于具有独特的性质&#xff0c…

引用类飘红,但是导入失败

背景&#xff1a; 引用类飘红&#xff0c;且显示可导入&#xff0c;但是导入一直失败。 列如下图&#xff0c;引导你可以导入依赖包&#xff0c;但是你发现按了导入他是导入不了的&#xff0c;就一直失败&#xff0c;就一直飘红 解决方案&#xff1a; 我们用一下idea的清理不…

IDEA中Debug的使用

自定义功能图表 功能说明 光标回到Debug行 执行到光标所在行 Force Step into Step into 进入JDK的配置 step into做了下述配置后&#xff0c;也可以和force step into一样进入到JDK中。 Trace Current Stream Chain Reset Frame 重置方法入栈 Force Return Break Point四…

【Spring Cloud精英指南】深度探索与实战:网关Gateway的高级应用与最佳实践

1. 前言 Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式&#xff0c;并为它们提供一些网关基本功能&#xff0c;…

警惕:与ChatGPT共享业务数据可能十分危险

您已经在使用ChatGPT了吗&#xff1f;或者您正在考虑使用它来简化操作或改善客户服务&#xff1f;虽然ChatGPT提供了许多好处&#xff0c;但重要的是&#xff0c;您要意识到与ChatGPT这样的人工智能工具共享敏感业务数据相关的安全风险。下面&#xff0c;我们概述了一些关键问题…

什么是 C 语言中的代码优化技巧?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

Javaweb09-数据库连接池技术

数据库连接池 1.数据库连接池基本概念&#xff1a; JDBC连接池是一个管理数据库连接的重要工具&#xff0c;它能够显著提高应用程序与数据库之间的性能和效率。连接池通过预先创建和维护一组数据库连接&#xff0c;而不是每次请求都创建新的连接&#xff0c;从而避免了频繁的…

js字符串文字添加不同颜色,replace的妙用$1...$9

更改字符串第一个数字为红色显示&#xff0c;第二个数字为黄色显示 $1匹配的是正则第一个括号选中的字符串&#xff0c;可以使用正则不断用括号匹配然后更改样式 const testStr "剩余12个名额&#xff0c;截止时间12月25日" testStr this.testStr.replace(/(\d)(\D…

【Python】 已解决:Python编码问题导致的SyntaxError

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;Python编码问题导致的SyntaxError 一、分析问题背景 在使用Python进行编程时&#xff0c;有时会遇到编码相关的问题。特别是在处理包含非ASCII字符&#xff08;…

算法复杂度详解( 超详细!)

前言&#xff1a; 今天&#xff0c;小编正式开始学习了数据结构的正式内容&#xff0c;学习了算法复杂度相关的内容&#xff0c;为了加强对这个的了解&#xff0c;于是诞生了这一篇文章&#xff0c;下面废话不多说&#xff0c;开始进入复杂度的详解&#xff01; 目录&#xff1…