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。

 

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