当前位置: 首页>后端>正文

RocketMQ(九)——indexFile

除了通过通常的指定Topic进行消息消费外,rocketMQ还提供了根据Key进行查询的功能。该查询是通过store目录中的index子目录中的indexFile进行索引实现的快速查询。

1.索引条目结构

每个Broker中会包含一组indexFile,每个indexFile都是以一个时间戳命名的(这个indexFile被创建时的时间戳)。每个indexFile文件由三部分构成:indexHeader,slots槽,indexes索引数据。每个IndexFile文件中包含500W个slot槽。而每个slot槽又可能会挂载很多的index索引单元。

RocketMQ(九)——indexFile,第1张

indexHeader固定40个字节,其中存放着如下数据:

RocketMQ(九)——indexFile,第2张
  • beginTimestamp:该indexFile种第一条消息的存储时间
  • endTimestamp:该indexFile种最后一条消息存储时间
  • beginPhyoffset:该indexFile种第一条消息在commitlog种的偏移量commitlog offset
  • endPhyoffset:该indexFile中最后一条消息在commitlog中的偏移量commitlog offset
  • hashSlotCount:已经填充有index的slot数量
  • indexCount:该indexFile中包含的索引单元个数

indexFile中最复杂的是Slots与Indexes间的关系。在实际存储时,Indexes是在Slots后面的,但为了便于理解,将他们的关系展示为以下形式:

RocketMQ(九)——indexFile,第3张

key的hash值 %500W的结果即为槽位,然后将该slot值修改为该index索引单元的indexNo,根据这个indexNo可以计算出该index单元在indexFile中的位置。由于取模结果的重复率还是很高的,为了解决这个问题,在每个Index索引单元中增加了preIndexNo,用于指定该slot种当前index索引单元的前一个index索引单元。相当于一个链表。

indexNo是一个在indexFile种的流水号,从0开始一次递增。即在一个indexFile中所有的indexNo是依次递增的。indexNo在index索引单元中是没有体现的,其是通过indexes中依次数出来的。

2.indexFile的创建

indexFile的文件名为当前文件被创建时的时间戳。

根据业务key进行查询时,查询条件除了key之外,还需要指定一个要查询的时间戳,表示要查询不大于该时间戳的最新的消息,即查询指定时间戳之前存储的最新消息。这个时间戳文件名可以简化拆线呢,提高查询效率。

index文件是何时创建的?

  • 当第一条带key的消息发送来后,系统发现没有indexFile,此时会创建第一个indexFile文件。
  • 当第一个indexFile中挂载的index索引单元数量超出2000W个时,会创建新的indexFile。当带key的消息发送到来后,系统会找到最新的indexFile,并从其indexHeader的最后4字节中读取到indexCount。
    若indexCount>=2000W时,会创建新的indexFile

3.查询流程

当消费者通过业务key来查询相应的消息时,其需要经过一个相对比较复杂的查询流程。
具体查询流程如下:

RocketMQ(九)——indexFile,第4张

https://www.xamrdz.com/backend/35b1936713.html

相关文章: