阅读 RocketMQ 存储源码时,沿“网络请求 → 消息校验 → CommitLog 追加 → 刷盘/复制 → ConsumeQueue 分发 → 拉取消费”走一条消息,不要从包名逐个类浏览。
Table of contents
Open Table of contents
一份正文,多份逻辑索引
CommitLog 以 Broker 为单位顺序追加消息正文和元数据。ConsumeQueue 按 Topic 与队列保存轻量逻辑位置,消费者先定位逻辑队列,再回到 CommitLog 读取正文。IndexFile 等索引支持按键检索,但不替代业务数据库。
RocketMQ 消息存储文档把这种结构概括为物理日志与轻量逻辑队列两层。统一顺序写提高吞吐,也意味着磁盘容量、保留期和清理是集群级工程问题。
写成功要问两次
刷盘决定进程或机器故障后本地数据是否保留,复制决定主节点故障后其他副本是否拥有数据。异步刷盘与异步复制延迟较低,但扩大故障丢失窗口;同步策略缩小窗口,也增加尾延迟和不可用概率。
因此“send 返回成功会不会丢”必须连同刷盘、复制、副本数量、确认条件和故障假设回答。不要只引用一个配置项。
高可用不等于无停顿
选主和副本切换期间,客户端可能超时、重试或收到重复。生产者以业务事件 ID 重试,消费者幂等;监控主从落后、CommitLog 写延迟、磁盘水位、Page Cache 压力、队列堆积年龄和清理失败。
源码实验建议给关键阶段打日志:物理 offset、队列 offset、刷盘结果、复制确认和消费位点。随后分别停止进程、隔离网络和填高磁盘,记录每次“成功响应”对应的数据位置。只有可重现的故障记录,才能支撑高可用结论。
下一步
继续阅读08-20 消息系统选型与常见事故,用同一组负载比较 RabbitMQ、Kafka 与 RocketMQ。