深入 RocketMQ 存储与原理
消息存储机制CommitLog 的设计与原理我们先从最核心的 CommitLog 说起。CommitLog 是什么简单说CommitLog 是 RocketMQ 存储消息的“主文件”。每个 Broker 上只有一个 CommitLog 文件严格说是有一组按大小滚动的文件所有 Topic 的所有消息都顺序写入到这个文件里。你可以把 CommitLog 想象成一本巨大的流水账本——不管是谁的消息来了就按顺序往本子上记先来先记后来后记绝不跳着写。为什么这么设计这里有个计算机存储的核心知识点磁盘顺序写入的速度比随机写入快几十甚至上百倍。为什么因为机械硬盘的读写依赖于磁头移动随机写入意味着磁头要到处“跳”每次跳跃都需要寻道时间平均约 5-10ms。而顺序写入磁头几乎不需要移动数据像流水一样连续不断地写到磁盘上。即使是 SSD顺序写入也能更好地利用带宽减少写放大效应。RocketMQ 正是利用了这个特性让所有消息都顺序追加到 CommitLog从而获得了极高的写入吞吐量。CommitLog 的文件结构CommitLog 在磁盘上是一个文件集合每个文件默认 1GB文件名就是起始偏移量用 20 位数字表示不足补 0~/store/commitlog/├── 00000000000000000000 (第1个文件偏移量 0 开始)├── 00000000001073741824 (第2个文件偏移量 1GB 开始)├── 00000000002147483648 (第3个文件偏移量 2GB 开始)└── …每个消息在 CommitLog 中的存储格式如下字段 长度 说明消息总长度 4 字节 整个消息条目的字节数消息序号 8 字节 消息的唯一递增序号存储时间戳 8 字节 消息存储时的时间戳消息体长度 4 字节 消息体的字节数消息体 变长 实际的消息内容扩展属性 变长 Topic、Tag、Key 等属性… … 其他元数据这样的设计意味着写入 CommitLog 完全不区分 Topic所有消息一视同仁顺序追加——这也是 RocketMQ 写入性能极高的根本原因。ConsumeQueue 的设计与原理如果 CommitLog 是所有消息的大杂烩那消费者怎么快速找到自己想要的消息呢这就是 ConsumeQueue 的用武之地。ConsumeQueue 是什么ConsumeQueue 是消息的“索引文件”每个 MessageQueue 对应一个 ConsumeQueue 文件。如果说 CommitLog 是“流水账本”那 ConsumeQueue 就是“分类目录”——它不存储消息本身只存储每条消息在 CommitLog 中的物理位置偏移量以及消息的大小和 Tag 的哈希值。ConsumeQueue 的存储格式每个 ConsumeQueue 条目固定 20 个字节非常轻量字段 长度 说明CommitLog 偏移量 8 字节 消息在 CommitLog 中的物理位置消息长度 4 字节 消息的字节数Tag 哈希码 8 字节 Tag 的哈希值用于消息过滤这意味着即使 CommitLog 有几十 GBConsumeQueue 也只有它的几十分之一大小可以轻松加载到内存中消费者查找消息时几乎不会产生磁盘 I/O。 小贴士这就是 RocketMQ 的“空间换时间”策略——用一个轻量的索引文件让消息查找从 O(n) 变成了 O(1)。CommitLog 与 ConsumeQueue 的协作关系CommitLog 和 ConsumeQueue 是怎么配合工作的下面这张图展示了它们之间的完整协作关系消费端存储层生产端发送消息顺序写入消息写入成功返回偏移量异步构建索引提取消息信息提取消息信息提取消息信息根据 Queue 和偏移量返回 CommitLog 偏移量根据物理偏移量精准读取返回消息体ProducerBrokerCommitLog单一文件所有消息共用ReputMessageService后台线程ConsumeQueueTopicA-Queue0ConsumeQueueTopicA-Queue1ConsumeQueueTopicB-Queue0Consumer整个协作流程分为写入链路和消费链路两条线写入链路图中的 1→2→3→4Producer 发送消息到 BrokerBroker 将消息顺序写入 CommitLog这一步就返回 ACK 给 Producer后台线程 ReputMessageService 异步地从 CommitLog 中解析消息根据消息所属的 Topic 和 Queue将索引信息写入对应的 ConsumeQueue消费链路图中的 5→6→7→85. Consumer 根据自己的消费进度Queue 偏移量查询 ConsumeQueue6. ConsumeQueue 返回消息在 CommitLog 中的物理偏移量7. Consumer 根据物理偏移量直接从 CommitLog 读取消息内容8. CommitLog 返回完整的消息体注意写入和构建索引是异步解耦的——消息一旦写入 CommitLog 就返回成功索引的构建在后台慢慢追。这就是 RocketMQ 写入延迟极低的原因之一。消息写入 CommitLog 的完整流程一条消息从 Producer 发出到最终落盘到底经历了哪些步骤我们用一张详细的流程图来还原是否同步刷盘异步刷盘Producer 发送消息消息到达 Broker消息合法性校验Topic 是否存在 / 消息体大小是否超限消息内容准备生成消息 ID / 时间戳 / 计算 CRC是否配置了消息轨迹记录消息轨迹数据获取当前 CommitLog 文件的写入位置全局锁将消息按固定格式序列化写入 CommitLog 的追加位置更新 CommitLog 的写入指针位置刷盘策略强制将数据从 PageCache刷入物理磁盘返回写入结果给 Producer数据仅在 PageCache 中等待后台线程异步刷盘后台线程 ReputMessageService异步构建 ConsumeQueue 索引消费者后续可消费到该消息步骤解析消息到达 BrokerProducer 通过网络将消息发送到 Broker 的指定端口合法性校验检查 Topic 是否存在、消息体是否超过 4MB默认限制等消息内容准备生成全局唯一的消息 ID记录到达时间戳计算 CRC 校验码消息轨迹记录可选如果开启了消息轨迹功能会记录消息的发送链路信息获取写入位置通过全局锁putMessageLock获取当前 CommitLog 文件的写入偏移量——注意这里是加锁的但因为是顺序写锁的持有时间极短不影响并发序列化写入将消息按照固定格式魔数、消息体大小、消息体、扩展属性等序列化为字节数组追加到 CommitLog 文件末尾更新指针更新内存中的写入位置指针为下一条消息做准备刷盘根据配置的刷盘策略决定是立即刷盘还是只写到操作系统缓存PageCache返回结果将写入状态成功/失败和消息 ID 返回给 Producer异步构建索引后台线程异步构建 ConsumeQueue 索引不影响主流程的响应速度ConsumeQueue 的异步构建机制ReputMessageService上面多次提到了 ReputMessageService这是 RocketMQ 中一个非常关键的后台服务。我们来深入了解一下它到底是怎么工作的。ReputMessageService 是什么它是 RocketMQ 中负责异步构建 ConsumeQueue 索引的后台线程服务。它像一个勤劳的“搬运工”不断从 CommitLog 中“搬运”消息的索引信息到对应的 ConsumeQueue 中。为什么需要异步构建如果每写入一条消息就同步去更新 ConsumeQueue会有两个问题增加了写入链路的延迟本来只需要写一次 CommitLog现在要写两次无法保证 ConsumeQueue 的写入也是顺序的不同 Topic/Queue 是分散的异步构建意味着写入 CommitLog 就立即返回成功索引在后台慢慢构建。ReputMessageService 的工作流程IndexFileConsumeQueueReputMessageServiceCommitLogProducerIndexFileConsumeQueueReputMessageServiceCommitLogProducer推动 CommitLog 的消费进度指针 (reputFromOffset)alt[有新数据][无新数据]loop[每毫秒轮询]发送消息写入 CommitLog返回写入成功不等待索引检查 CommitLog 是否有新数据解析新消息的物理位置和属性计算 ConsumeQueue 偏移量写入索引条目如果配置了 IndexFile构建哈希索引短暂休眠等待下一轮关键点ReputMessageService 会记录一个 reputFromOffset 指针标记当前已构建到 CommitLog 的哪个位置每次轮询时从该位置读取新数据构建索引然后更新指针如果某条消息的 Topic 或 Queue 不存在ReputMessageService 会跳过并继续同时记录错误日志这种设计保证了即便索引构建失败原始消息依然安全地存储在 CommitLog 中数据不会丢失消息的索引文件IndexFile的作用除了 ConsumeQueue 这个“主索引”RocketMQ 还有一个 IndexFile索引文件用于支持根据消息 Key 查询消息。IndexFile 是什么IndexFile 是一个基于哈希索引的查询文件用于快速定位消息在 CommitLog 中的位置。IndexFile 的结构索引条目结构每条 20 字节Key 的哈希值4 字节CommitLog 偏移量8 字节消息存储时间差4 字节同哈希槽的下一条索引4 字节IndexFile 文件结构文件头部创建时间、消息总数、哈希槽数量等哈希槽数组默认 500 万个槽位索引条目数组默认 2000 万条Key 查询流程Producer 发送消息时指定 Key例如订单 IDBroker 在构建索引时对 Key 进行哈希运算存入 IndexFile用户通过控制台或 API 查询时输入 Key 值Broker 对 Key 进行同样的哈希运算在 IndexFile 中找到对应的消息位置再通过 CommitLog 偏移量读取完整消息 小贴士ConsumeQueue 和 IndexFile 的区别在于——ConsumeQueue 用于按队列顺序消费IndexFile 用于按业务 Key 精确查询。一个是“扫货架”一个是“查字典”。

相关新闻

模板驱动文档自动化:零代码生成专业PDF/Word

模板驱动文档自动化:零代码生成专业PDF/Word

1. 项目概述:当文档生产变成“填空题”,而不是“写作文”你有没有经历过这种场景:每周一早上,市场部同事准时把一份《月度客户反馈摘要》模板发到群里,要求销售、客服、产品三个部门各自填入数据,再汇总成P…

2026/10/13 15:58:42 阅读更多 →
UE5动画重定向实战:从原理到应用,提升角色动画开发效率

UE5动画重定向实战:从原理到应用,提升角色动画开发效率

1. 项目概述:为什么动画重定向是UE5项目开发的效率倍增器在任何一个使用虚幻引擎5(UE5)开发角色扮演、动作冒险或任何包含大量角色的项目中,动画师和程序员最头疼的问题之一,可能就是“角色复用”。想象一下&#xff0…

2026/10/13 15:58:24 阅读更多 →
生产级机器学习服务架构:从模型上线到业务闭环

生产级机器学习服务架构:从模型上线到业务闭环

1. 这不是“跑通模型”就完事的课——它讲的是模型怎么在真实业务里活下来“From Notebook to Production: Running ML in the Real World (Part 4)”这个标题,光看前半句容易误以为是又一篇教你怎么把Jupyter里训练好的模型导出成pkl文件的教程。但关键在后半句——…

2026/10/13 16:38:56 阅读更多 →

最新新闻

批量插入性能优化全解析:从一次线上事故到系统设计落地

批量插入性能优化全解析:从一次线上事故到系统设计落地

上周刚处理完一个线上事故——业务方导了一份几百万行的数据文件过来,平台接口直接卡死,数据库连接数被打满,单条INSERT平均耗时飙到几十毫秒,整个写入链路像堵死了一样。翻监控的时候我发现一个很扎心的事实:这批数据…

2026/10/14 2:59:30 阅读更多 →
ggggggggit

ggggggggit

1.git介绍Git是一个开源的版本控制系统,常用于项目代码管理,文件管理等场景。可以简单理解为一个仓库,用来存储并管理你存入的东西。最重要的一个功能就是版本管理。git服务会记录每一次修改历史,用户可以翻看历史版本或者还原到某…

2026/10/14 2:59:30 阅读更多 →
mysqldump备份实战:逻辑备份、增量恢复与常见坑解析

mysqldump备份实战:逻辑备份、增量恢复与常见坑解析

一、聊聊为什么到今天还要认真写mysqldump我知道在座的各位可能已经在用各种图形化工具、云平台备份服务,或者开源的物理备份方案了。但说句实在话,我在处理日常运维和故障恢复的时候,最常摸到的还是mysqldump。它确实老,也确实朴…

2026/10/14 2:59:30 阅读更多 →
告别琐碎Review:Pylint与Flake8让Python代码质量自动化

告别琐碎Review:Pylint与Flake8让Python代码质量自动化

代码评审的时候,我经常在 PR 里看到三类东西:缩进一会儿空格一会儿 Tab,几个没用的 import 堆在那里,还有一个函数参数多到要翻两屏才看完。这种问题不算致命,但会反复出现——只要项目里没有一套自动化的检查机制&…

2026/10/14 2:59:30 阅读更多 →
macOS 窗口管理新选:Loop 免费开源,触发键一步到位

macOS 窗口管理新选:Loop 免费开源,触发键一步到位

macOS 窗口管理新选:Loop 免费开源,触发键一步到位 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 编辑器、终端、浏览器挤在一块屏幕上,想分屏只能手动拖&#xff0…

2026/10/14 2:59:30 阅读更多 →
DSPE-PEG2K-转铁蛋白复合物的靶向递送机制与应用

DSPE-PEG2K-转铁蛋白复合物的靶向递送机制与应用

1. 项目概述:DSPE-PEG2K-转铁蛋白复合物的核心价值在靶向药物递送领域,DSPE-PEG2K-转铁蛋白(DSPE-PEG2000-Transferrin)这类磷脂-聚乙二醇-蛋白质复合物正成为突破血脑屏障和肿瘤靶向的关键材料。作为在生物材料领域深耕多年的研究…

2026/10/14 2:58:30 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →