Java充电社
专辑
博文
联系我
本人继续续收门徒,亲手指导
RocketMQ第12篇:原理篇-indexfile
相关专辑:
RocketMQ专题
<div style="display:none"></div> ## indexFile 除了通过通常的指定Topic进行消息消费外,RocketMQ还提供了根据key进行消息查询的功能。该查询是通过store目录中的index子目录中的indexFile进行索引实现的快速查询。当然,这个indexFile中的索引数据是在包含了key的消息被发送到Broker时写入的。如果消息中没有包含key,则不会写入。 ## 1、索引条目结构 每个Broker中会包含一组indexFile,每个indexFile都是以一个时间戳命名的(这个indexFile被创建时的时间戳)。每个indexFile文件由三部分构成:indexHeader,slots槽位,indexes索引数据。每个indexFile文件中包含500w个slot槽。而每个slot槽又可能会挂载很多的index索引单元。 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/360/36452212-6dcc-406b-a26f-5e638215a0c6.png) ndexHeader固定40个字节,其中存放着如下数据: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/360/d8b6ff35-808f-4bec-959e-21b1497a6725.png) - beginTimestamp:该indexFile中第一条消息的存储时间 - endTimestamp:该indexFile中最后一条消息存储时间 - beginPhyoffset:该indexFile中第一条消息在commitlog中的偏移量commitlog offset - endPhyoffset:该indexFile中最后一条消息在commitlog中的偏移量commitlog offset - hashSlotCount:已经填充有index的slot数量(并不是每个slot槽下都挂载有index索引单元,这里统计的是所有挂载了index索引单元的slot槽的数量) - indexCount:该indexFile中包含的索引单元个数(统计出当前indexFile中所有slot槽下挂载的所有index索引单元的数量之和) indexFile中最复杂的是Slots与Indexes间的关系。在实际存储时,Indexes是在Slots后面的,但为了便于理解,将它们的关系展示为如下形式: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/360/6b297dd7-57a2-40f9-aea8-6f5f19f8e0b0.png) key的hash值 % 500w的结果即为slot槽位,然后将该slot值修改为该index索引单元的indexNo,根据这个indexNo可以计算出该index单元在indexFile中的位置。不过,该取模结果的重复率是很高的,为了解决该问题,在每个index索引单元中增加了preIndexNo,用于指定该slot中当前index索引单元的前一个index索引单元。而slot中始终存放的是其下最新的index索引单元的indexNo,这样的话,只要找到了slot就可以找到其最新的index索引单元,而通过这个index索引单元就可以找到其之前的所有index索引单元。 > indexNo是一个在indexFile中的流水号,从0开始依次递增。即在一个indexFile中所有indexNo是以此递增的。indexNo在index索引单元中是没有体现的,其是通过indexes中依次数出来的。 index索引单元默写20个字节,其中存放着以下四个属性: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/360/a53c9bd3-1327-43d1-bb3e-2eb899f97397.png) - keyHash:消息中指定的业务key的hash值 - phyOffset:当前key对应的消息在commitlog中的偏移量commitlog offset - timeDiff:当前key对应消息的存储时间与当前indexFile创建时间的时间差 - preIndexNo:当前slot下当前index索引单元的前一个index索引单元的indexNo ## 2、indexFile的创建 indexFile的文件名为当前文件被创建时的时间戳。这个时间戳有什么用处呢? 根据业务key进行查询时,查询条件除了key之外,还需要指定一个要查询的时间戳,表示要查询不大于该时间戳的最新的消息,即查询指定时间戳之前存储的最新消息。这个时间戳文件名可以简化查询,提高查询效率。具体后面会详细讲解。 indexFile文件是何时创建的?其创建的条件(时机)有两个: - 当第一条带key的消息发送来后,系统发现没有indexFile,此时会创建第一个indexFile文件 - 当一个indexFile中挂载的index索引单元数量超出2000w个时,会创建新的indexFile。当带key的消息发送到来后,系统会找到最新的indexFile,并从其indexHeader的最后4字节中读取到indexCount。若indexCount >= 2000w时,会创建新的indexFile。 由于可以推算出,一个indexFile的最大大小是:(40 + 500w * 4 + 2000w * 20)字节 ## 3、查询流程 当消费者通过业务key来查询相应的消息时,其需要经过一个相对较复杂的查询流程。不过,在分析查询流程之前,首先要清楚几个定位计算式子: ```shell 计算指定消息key的slot槽位序号: slot槽位序号 = key的hash % 500w (式子1) ``` ```shell 计算槽位序号为n的slot在indexFile中的起始位置: slot(n)位置 = 40 + (n - 1) * 4 (式子2) ``` ```shell 计算indexNo为m的index在indexFile中的位置: index(m)位置 = 40 + 500w * 4 + (m - 1) * 20 (式子3) ``` > 40为indexFile中indexHeader的字节数 > > 500w * 4 是所有slots所占的字节数 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/360/4d06fe3c-23ea-436e-9879-52897caa0e17.png) <a style="display:none" target="_blank" href="https://mp.weixin.qq.com/s/_S1DD2JADnXvpexxaBwLLg" style="color:red; font-size:20px; font-weight:bold">继续收门徒,亲手带,月薪 4W 以下的可以来找我</a> ## 最新资料 1. <a href="https://mp.weixin.qq.com/s?__biz=MzkzOTI3Nzc0Mg==&mid=2247484964&idx=2&sn=c81bce2f26015ee0f9632ddc6c67df03&scene=21#wechat_redirect" target="_blank">尚硅谷 Java 学科全套教程(总 207.77GB)</a> 2. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484192&idx=1&sn=505f2faaa4cc911f553850667749bcbb&scene=21#wechat_redirect" target="_blank">2021 最新版 Java 微服务学习线路图 + 视频</a> 3. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484573&idx=1&sn=7f3d83892186c16c57bc0b99f03f1ffd&scene=21#wechat_redirect" target="_blank">阿里技术大佬整理的《Spring 学习笔记.pdf》</a> 4. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484544&idx=2&sn=c1dfe907cfaa5b9ae8e66fc247ccbe84&scene=21#wechat_redirect" target="_blank">阿里大佬的《MySQL 学习笔记高清.pdf》</a> 5. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485167&idx=1&sn=48d75c8e93e748235a3547f34921dfb7&scene=21#wechat_redirect" target="_blank">2021 版 java 高并发常见面试题汇总.pdf</a> 6. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485664&idx=1&sn=435f9f515a8f881642820d7790ad20ce&scene=21#wechat_redirect" target="_blank">Idea 快捷键大全.pdf</a> ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/1/2883e86e-3eff-404a-8943-0066e5e2b454.png)
相关专辑:
RocketMQ专题