RocketMQ的commitlog索引文件indexfile生成规则

Indexfile的文件存储结构

Index File Struct

 

Indexfile的逻辑关系

一个文件大小约400M

 

Table 1 Index File关系图

 

使用messagekey查询

IndexFile消息的索引文件,存储消息Key与Offset的对应关系。
如果一个消息包含key值的话,会使用IndexFile存储消息索引,文件的内容结构如图:
消息索引。是否建立索引可以通过配置文件配置。
索引文件主要用于根据key来查询消息的

创建过程: 

将消息索引键与消息偏移量映射关系写入到IndexFile的实现方法名称:

public boolean putKey(final String key, final long phyOffset, final long storeTimestamp)

 

S1:向IndexFile中写入索引消息

if (this.indexHeader.getIndexCount() < this.indexNum) {

            int keyHash = indexKeyHashMethod(key);

            int slotPos = keyHash % this.hashSlotNum;

            int absSlotPos = IndexHeader.INDEX_HEADER_SIZE + slotPos * hashSlotSize;

}

如果已使用条目小于最大条目,索引文件满,返回false。否则计算hash。

根据Key计算hashcode,计算公式是String自带的。

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。空字符串的哈希值为 0

keyHash 对哈希槽数量(hashSlotNum)取余,即hashcode对应的hash槽下标。

最后计算物理地址等于index头部(固定的40字节) +hash槽大小*逻辑下标。

 

S2:读取槽存储数据

如果值小于等于0,表示消息第一次创建索引

如果大于0,表示索引存在。

int slotValue = this.mappedByteBuffer.getInt(absSlotPos);

if (slotValue <= invalidIndex || slotValue > this.indexHeader.getIndexCount()) {

                  slotValue = invalidIndex; }

 

S3:更新时间戳

S4:将详细信息存储到IndexFile           

int absIndexPos =

                    IndexHeader.INDEX_HEADER_SIZE + this.hashSlotNum * hashSlotSize

                        + this.indexHeader.getIndexCount() * indexSize;



                this.mappedByteBuffer.putInt(absIndexPos, keyHash);

                this.mappedByteBuffer.putLong(absIndexPos + 4, phyOffset);

                this.mappedByteBuffer.putInt(absIndexPos + 4 + 8, (int) timeDiff);

//冲突的hash值得上一个消息的索引index,即获取的slotvalue

                this.mappedByteBuffer.putInt(absIndexPos + 4 + 8 + 4, slotValue);

                         //将当前的槽的当前索引index值存入槽的位置,槽中值始终保持最新

                this.mappedByteBuffer.putInt(absSlotPos, this.indexHeader.getIndexCount());

S5:累计更新文件索引头信息。如果是第一条信息,更新开始时间。

 

根据索引Key查找信息的实现:

public void selectPhyOffset(final List<Long> phyOffsets, final String key, final int maxNum,

        final long begin, final long end, boolean lock)

 

S1:计算方法跟putkey的S1相同。获取到对应的hash槽中存储的条目的数据索引。如果没有数据条目直接返回。

S2:循环查找hash冲突,根据slotvalue定位到Hash槽最新的一个条目,然后依次查找上一条index。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章