阿里面试: RocketMQ如何实现每秒上十万QPS的超高吞吐量读取的?

devtools/2024/10/9 4:33:48/

这玩意儿表面看上去挺牛逼,但其实背后的逻辑和套路,在咱们开发里见过的那些招数,都能找到影子。

今天小北和大家一起系统化的梳理梳理一遍,让大家功力猛增,吊打面试官。

1. 消息存储:巧妙利用顺序写

先说说消息存储。RocketMQ这货聪明得很,它用了顺序写这个绝招。

啥叫顺序写?

简单点讲,就是把消息按顺序往磁盘上写,省得磁盘脑袋疼。这和随机写比起来,效率高出好几条街。顺序写的好处在于磁盘的磁头不用东一头西一头地乱晃,直接一路跑下去,速度自然快得飞起。

为啥这个重要?

因为你要是搞随机写,那磁盘就得不断地在不同位置读写,时间全花在寻道上了。顺序写不需要来回折腾,直接就省下了大把时间,让RocketMQ在存储消息的时候跟打了鸡血似的,快速写入,简直停不下来。

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。这是大佬写的,7701页的BAT大佬写的刷题笔记,让我offer拿到手软

2. 消息读取:多线程并发

再说说读取。你可能会问:“为啥读取也这么快?”

因为,RocketMQ这货是多线程并发搞定的。

它把消息分散到多个队列里,然后搞一堆线程来处理,谁也不耽误谁。这就跟多人同时搬砖一样,一个人搬一块肯定累死累活,一群人同时上,那砖堆嗖嗖就没了。

但多线程处理也不是说你线程越多越好。这事儿要是没控制好,线程多了反而会互相抢资源,搞不好还得打架。

RocketMQ在这块儿也动了不少脑筋,通过精细化管理线程池,保证每个线程都干自己的活,互不干扰,效率拉满。

3. 数据结构优化:减少I/O

RocketMQ里还用了不少数据结构上的小聪明。最重要的就是commitLog,这玩意儿是个append-only的结构

啥意思?就是消息只往里追加,不回头改。

这么干的好处是啥?

减少I/O操作,写入速度更快。而且,你追加写入的时候,也不用老是锁住整个文件,只需要锁住当前写入的位置就行,这样能大大减少锁的竞争,提升并发性能。

另外,RocketMQ还用上了内存映射文件(MappedFile)这种骚操作。把磁盘文件映射到内存中,操作起来跟直接读写内存差不多,虽然底层还是磁盘,但从开发者的角度看,I/O操作几乎是瞬间完成的,这也解释了为啥它的读写速度能跑得那么快。

4. 批量操作:减少频繁的网络交互

再来看看它的批量操作。这个其实挺简单的,RocketMQ这货并不是每收到一条消息就立马去写磁盘或者发送网络请求,它把消息攒到一定数量再统一处理,这就叫批量操作。

为啥要这么干?

因为频繁的网络交互和磁盘I/O都是时间黑洞,一个操作时间长,另一边就得等着。这一攒消息,就把这些操作给优化了,消息不至于像水龙头滴水一样流,而是一瓢一瓢地泼。

这个招数也不是谁都能用的,有些场景讲究时效性,不能等。但RocketMQ通过精确控制批量的大小和延时,既保证了性能,又不会让消息堆积太久,这就叫平衡得当。

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。这是大佬写的,7701页的BAT大佬写的刷题笔记,让我offer拿到手软

5. 数据复制:异步复制和主从架构

最后一招就是数据复制。数据存储里最重要的一个环节就是容灾备份,这就要说到RocketMQ的异步复制和主从架构。

异步复制是个啥意思?

你写完数据不用等所有备份都完成,先让写操作返回,备份的事儿咱慢慢来。这样主节点就不至于被拖慢,能继续高速处理新的请求。

至于主从架构,这货其实就是主节点负责主要的写操作,从节点负责读取和备份。通过分工合作,读取请求就不会把主节点的资源吃光,让系统的整体吞吐量进一步提高。

6. 零拷贝

零拷贝的本质就是减少CPU在数据传输中的干预,让数据在内存和磁盘之间流动时不经过用户态。

这是个啥概念呢?

平时咱们操作系统要读取一个文件,比如从磁盘读到内存,然后再发给网络,这个过程中数据一般要经过4次拷贝。
如下图:

通常会是从磁盘到内核缓冲区,再从内核缓冲区拷贝到用户态的应用程序缓冲区,最后再从应用程序缓冲区回到内核缓冲区,最终发到网络上。

这几趟下来,CPU忙得不可开交,性能也就损失了一大截。

零拷贝就是把这个中间过程简化到最少。

RocketMQ利用操作系统的零拷贝技术,让数据直接从内核缓冲区传到网络上,完全跳过了用户态的拷贝。

这么做的好处是啥?

减少了不必要的CPU占用,同时提高了数据传输的效率。特别是在处理大文件或大量消息时,零拷贝的作用尤为明显,它能大大降低系统的负载,让RocketMQ在高吞吐量场景下依然保持流畅。

总结:不止是快,更是稳

总的来说,RocketMQ能实现每秒上十万QPS的超高吞吐量,靠的就是这些个聪明的策略和优化。

它在存储、读取、I/O、网络交互以及数据复制上都动了不少脑筋,每一块儿都拿捏得死死的。你别看它搞得玄乎,其实就是把咱们开发中遇到的瓶颈一个一个给突破了。

RocketMQ不止是快,更重要的是稳。稳到你几乎感觉不到它的存在,一切都在后台默默搞定。这也就解释了为啥这么多人爱用它——少折腾,效率高。

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!


http://www.ppmy.cn/devtools/123191.html

相关文章

【Git原理与使用】远程操作标签管理

远程操作&&标签管理 1.理解分布式版本控制系统2.新建远程仓库3.克隆远程仓库4.向远程仓库推送5.拉取远程仓库6.配置 Git7.配置命令别名8.标签管理8.1创建标签8.2操作标签 点赞👍👍收藏🌟🌟关注💖💖…

算法知识点————贪心

贪心:只考虑局部最优解,不考虑全部最优解。有时候得不到最优解。 DP:考虑全局最优解。DP的特点:无后效性(正在求解的时候不关心前面的解是怎么求的); 二者都是在求最优解的,都有最优…

SpringBoot中,接口签名,通用方案,以确保接口的安全性

1. 为什么需要接口签名? 接口签名目的:防止第三方伪造请求。请求伪造:未经授权的第三方构造合法用户的请求来执行不希望的操作。转账接口示例:展示了如果接口没有安全措施,第三方可以轻易伪造请求,例如将资…

springboot自动配置

自动配置的核心就在SpringBootApplication注解上,SpringBootApplication这个注解 底层包含了3个注解,分别是: SpringBootConfiguration ComponentScan EnableAutoConfiguration EnableAutoConfiguration这个注解才是自动配置的核心,它 封…

Android2024.2.1升级错误

提示 Gradle 版本不兼容,升级后就报错了 。 1.gradle安装包镜像 //distributionUrlhttps\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-8.5-bin.zip //镜像 2. Build报错&#xff1a…

基于 Seq2Seq 的中英文翻译项目(pytorch)

项目简介 本项目旨在使用 PyTorch 构建一个基于 Seq2Seq(编码器-解码器架构)的中英文翻译模型。我们将使用双语句子对的数据进行训练,最终实现一个能够将英文句子翻译为中文的模型。项目的主要步骤包括: 数据预处理:…

[ESP32]ESP-IDF使用组件添加U8g2图形库

U8g2 在ESP32使用u8g2的时候可以使用添加component的方式进行, 由于官方的component库没有, 这里我找到了一个可以使用的github库, 使用git的方式进行添加这一个库 具体的原理可以看[官方手册](https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-guides/to…

记HttpURLConnection下载图片

目录 一、示例代码1 二、示例代码2 一、示例代码1 import java.io.*; import java.net.HttpURLConnection; import java.net.URL;public class Test {/*** 下载图片*/public void getNetImg() {InputStream inStream null;FileOutputStream fOutStream null;try {// URL 统…