broker的消息存储做了那些事
rocketMq的broker消息存储主要包括3个部分,分别commitLog的存储,consumeQueue的存储,index的存储,这章分享会把这三个过程分解清楚,同时会对里面涉及的存储位置的偏移量着重讲解清楚。
1、commitLog的存储是producer发送消息给broker端broker同步处理的
2、consumeQueue和index两者存储其实是一个定时任务从commitLog中获取偏移量然后存储过去的
3、consumeQueue和index的存储 与 commitLog的存储是隔离开的,非同步的
broker的消息存储过程
![img_4bbe359db4b712e255b4175e59c26749.png](https://i-blog.csdnimg.cn/blog_migrate/da5ce3b16d98ddefd03981934fd1b3ae.png)
说明:分享自再说rocketmq消息存储。
1、commitLog其实有两层够层,其中MappendFileQueue是逻辑的存储队列概念,里面保存着顺序增长的MappedFile文件。
2、MappedFile文件是真正存储实际数据的文件
3、在整个broker的存储体系中,MappedFile文件保存了commitLog、consumeQueue、Index等,是核心的数据结构。
broker的消息存储过程
![img_1be29be705ea7f595acb23cbb3fa882d.png](https://i-blog.csdnimg.cn/blog_migrate/28430437ac449531eccdcfa3f9765aa2.png)
说明:参见BrokerController类
1、其中sendProcessor就是broker端接收message的入口函数
![img_7058e683f1589d36de01e2c8fe03eaa7.png](https://i-blog.csdnimg.cn/blog_migrate/987a4dd216e3a2178e3d16ca6f860a68.png)
说明:参见SendMessageProcessor类
1、这里我们先看下单个消息的处理过程,也就是sendMessage过程
![img_e6cd27da6ab752971c6eeb5e76ba38e8.png](https://i-blog.csdnimg.cn/blog_migrate/22cb57f5bfde89f946027d3f49610942.png)
说明:参见SendMessageProcessor类
1、putMessage函数开始执行数据的保存
![img_7f01bb00a29f4ea1259766a5ab8999e3.png](https://i-blog.csdnimg.cn/blog_migrate/74d1b45f0be388cf6684c83938ea647e.png)
说明:参见DefaultMessageStore类
1、commitLog.putMessage开始进入commitLog的保存逻辑
![img_4da135daa6575701ce2b190909576056.png](https://i-blog.csdnimg.cn/blog_migrate/ebb23332a452271ce88eec1254f28ae5.png)
说明:参见CommitLog类
1、先从mappedFileQueue获取最后一个MappedFile文件,如果为空就创建一个commitLog对应的MappedFile文件,文件命名以实际以文件大小命名,分别是00000000000000000000、00000000001073741824、00000000002147483648,文件名之间差1G=1024*1024*1224B=1073741824。每个commitLog的MappedFile文件大小是1G,剩余多余无非存入新消息就用填充字符填充到1G。
2、mappedFile.appendMessage执行保存消息到MappedFile的动作
![img_30b414f1ff7bc4a2b1e8c4110bdc7bc9.png](https://i-blog.csdnimg.cn/blog_migrate/3bcee78dde53c955017122ca062aca25.png)
说明:参见MappedFile类
1、这里我们以单个消息存储为例继续说明
![img_c752ee632f609fa9f0f5a71006f138df.png](https://i-blog.csdnimg.cn/blog_migrate/8412d186ec29bff86a1c1f1369bdcb0d.png)
说明:参见CommitLog类
1、做一些前置准备,包括计算下一个存储位置等
![img_f460554004fdb7effde393e01978405b.png](https://i-blog.csdnimg.cn/blog_migrate/12f556fe0a5c0c4c0d8dcdf94df700f2.png)
说明:参见CommitLog类
1、这里有个特别的地方需要注意,就是如果剩余空间无法装下消息+8个字节的结束标识符,就默认结束了,结束标识符应该用于标识mappedFile是否结束。
![img_5f6fabc3f5c37c02c8ce4c4fd19c5991.png](https://i-blog.csdnimg.cn/blog_migrate/8c0af87a2ebfcf8e0227284713f89c71.png)
说明:参见CommitLog类
1、这里的消息写入过程我们分析暂时到写入缓存就结束了,真正实际上是还会有刷盘的动作的,这里暂时不展开分析,后续单独开一章刷盘的的分析。
![img_7b2a1c6329e4307e9c7a7726bc020f8e.png](https://i-blog.csdnimg.cn/blog_migrate/13091158e7c5f80ed2ddf5adbceeb692.png)
说明:
commitLog的MappedFile文件中保存的数据格式如上图所示,在末尾不能保存整个消息的时候就会重新生成一个MappedFile文件,当然在末尾应该会有填充结束标识符,文件结束符是以特殊magic_code结束的,为BLANK_MAGIC_CODE=0xBBCCDDEE ^1880681586 +8;
comsumeQueue的存储过程
![img_aca704db1d9f9b11495d37543d447e30.png](https://i-blog.csdnimg.cn/blog_migrate/a623fc433215017cfd6f828524e78e94.png)
说明:参见DefaultMessageStore类
1、该实现类是一个线程函数,内部通过run操作循环去commitLog去消息位移信息保存到consumeQueue当中
![img_209fac7f48c7e241f3bf3bc7769910cf.png](https://i-blog.csdnimg.cn/blog_migrate/b5d2584ca708bf17872b71f337259796.png)
说明:参见DefaultMessageStore类
![img_42c77ae531a9c598b89cc625de17c684.png](https://i-blog.csdnimg.cn/blog_migrate/c7860a5bf80b7abd9e28979567aaf9eb.png)
说明:参见DefaultMessageStore类
1、this.dispatcherList.addLast(new CommitLogDispatcherBuildConsumeQueue());
2、this.dispatcherList.addLast(new CommitLogDispatcherBuildIndex());
![img_742d5d19e4698d7c606c4fab69d5dd0e.png](https://i-blog.csdnimg.cn/blog_migrate/daa2a4440a47619090d321bf5308fbfb.png)
![img_1d8454c609384f5b726629338baa2049.png](https://i-blog.csdnimg.cn/blog_migrate/4528332a5124e9aa3c7a73091f10e585.png)
说明:参见ConsumeQueue类
1、ConsumeQueue的消息单元格式如下图。
![img_d82f417382a572ac1baae3823ad3197d.png](https://i-blog.csdnimg.cn/blog_migrate/a1ded64023b06be1fc658458a877828f.png)