学习文档:
1.RocketMQ高性能之底层存储设计 https://juejin.cn/post/6844903728521166856
2.https://www.cnblogs.com/duanxz/p/5020398.html
3.//www.greatytc.com/p/e0befd11aee0
核心问题
对RocketMq整体存储架构设计的认知
RocketMQ文件布局

CommitLog和ConsumeQueue

CommitLog
一个文件集合,每个文件1G大小,存储满后存下一个,为了讨论方便可以把它当成一个文件,所有消息内容全部持久化到这个文件中;因为是日志式的存储,基本都是顺序写;
ConsumeQueue
消息消费的逻辑队列,作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。而IndexFile(索引文件)则只是为了消息查询提供了一种通过key或时间区间来查询消息的方法(ps:这种通过IndexFile来查找消息的方法不影响发送与消费消息的主流程)。从实际物理存储来说,ConsumeQueue对应每个Topic和QueuId下面的文件。单个文件大小约5.72M,每个文件由30W条数据组成,每个文件默认大小为600万个字节,当一个ConsumeQueue类型的文件写满了,则写入下一个文件;
IndexFile
因为所有的消息都存在CommitLog中,如果要实现根据 key 查询 消息的方法,就会变得非常困难,所以为了解决这种业务需求,有了IndexFile的存在。用于为生成的索引文件提供访问服务,通过消息Key值查询消息真正的实体内容。在实际的物理存储上,文件名则是以创建时的时间戳命名的,固定的单个IndexFile文件大小约为400M,一个IndexFile可以保存 2000W个索引;
Mapped文件
可以直接将对于内存的操作写在PageCache;而非需要多次copy
整体存储流程


整体看出RocketMQ的存储设计比较简单
元数据存储在CommitLog里,通过CommitLog创建ConsumeQueue和IndexFile文件(两个文件都是索引)
ConsumeQueue用于构建内存中队列用于消费,支持按照时间查询消息(二分搜索)
IndexFile就是提供MsgKey或MsgId查询的功能
HashSlot就是对应每一个Hash值的链表的表头,Index则是每个链表的节点
首先根据MsgKey或许MsgId算出HashSlot,然后利用HashSlot来找到链表表头,不断遍历找到对应的节点
