存储
知识点:零拷贝、用户态内核态切换、页缓存
文件存储结构
- 混合存储的结构(多个 Topic 的消息实体内容都存储于一个 CommitLog 中)
- 数据与索引分离(CommitLog 为数据,ConsumeQueue 和 IndexFile 为索引)
CommitLog
消息元数据主体数据
顺序写入,文件名称中的数值可以表示当前文件数据的偏移量
ConsumeQueue
消息消费队列
保存了指定 Topic 下的队列消息在 CommitLog 中的起始物理偏移量 offset,消息大小 size 和消息 Tag 的 HashCode 值。
consumequeue 文件可以看成是基于 topic 的 commitlog 索引文件
IndexFile
hash 索引
可以通过 key 或者时间查询消息
消息刷盘
- 同步刷盘:只有在消息真正持久化至磁盘后 RocketMQ 的 Broker 端才会真正返回给 Producer 端一个成功的 ACK 响应。同步刷盘对 MQ 消息可靠性来说是一种不错的保障,但是性能上会有较大影响,一般适用于金融业务应用该模式较多。
- 异步刷盘:能够充分利用 OS 的 PageCache 的优势,只要消息写入 PageCache 即可将成功的 ACK 返回给 Producer 端。消息刷盘采用后台异步线程提交的方式进行,降低了读写延迟,提高了 MQ 的性能和吞吐量。
高性能 IO
- 页缓存,顺序读取的时候,性能接近内存。
- 零拷贝,RocketMQ 主要通过 MappedByteBuffer 对文件进行读写操作。其中,利用了 NIO 中的 FileChannel 模型将磁盘上的物理文件直接映射到用户态的内存地址中。
Simple is Awesome