系列
概述
? ? 這篇文章主要是想講清楚rocketMq中index的存儲和查詢功能,著重分為存儲和查詢兩個點進行講解足画,這里需要支持的是這篇博文還是參考了很多互聯網人的已有成果(就是站在了前人的肩膀上)蜈出,參考文章會在文章引用中列出漫蛔。
index數據結構
? ? index的數據結構總共包括header歉胶,slot乡摹,index總計3個部分組成,各個部分的格式如下圖所示昧狮,其中slot可以保存500萬slot璧亮,index部分可以保存2000萬index萧诫。
header結構
說明:
????1. beginTimestamp : 該索引文件的第一個消息(Message)的存儲時間(落盤時間) 物理位置(pos: 0-7) 8bytes
????2. endTimestamp : 該索引文件的最后一個消息(Message)的存儲時間(落盤時間) 物理位置(pos: 8-15) 8bytes
????3. beginPhyoffset : 該索引文件第一個消息(Message)的在CommitLog(消息存儲文件)的物理位置偏移量(可以通過該物理偏移直接獲取到該消息) 物理位置(pos: 16-23) 8bytes
????4. endPhyoffset : 該索引文件最后一個消息(Message)的在CommitLog(消息存儲文件)的物理位置偏移量 (pos: 24-31) 8bytes
????5. hashSlotCount : 該索引文件目前的hash slot的個數 (pos: 32-35) 4bytes
????6. indexCount : 該索引文件目前的索引個數 (pos: 36-39) 4bytes
說明:
? ? slot每個節(jié)點保存當前已經擁有多少個index數據了。
說明:
????1. key hash value: message key的hash值
????2. phyOffset: message在CommitLog的物理文件地址, 可以直接查詢到該消息(索引的核心機制)
????3. timeDiff: message的落盤時間與header里的beginTimestamp的差值(為了節(jié)省存儲空間枝嘶,如果直接存message的落盤時間就得8bytes)
????4. prevIndex: hash沖突處理的關鍵之處, 相同hash值上一個消息索引的index(如果當前消息索引是該hash值的第一個索引帘饶,則prevIndex=0, 也是消息索引查找時的停止條件),每個slot位置的第一個消息的prevIndex就是0的群扶。
存儲過程
? ? 1及刻、首先判斷下index是否查處最大限制,沒有超出則繼續(xù)執(zhí)行
? ? 2竞阐、根據key計算hash值%hashSlotNum得出具體安放slot的位置
? ? 3缴饭、計算真正放置slot的物理位置偏移
? ? 4、生成index對象并按照格式放置所有字段骆莹,其中我們注意一下slotValue颗搂,該hash位置第一次放置的時候slotValue的值為0,后面放置的slotValue是前一次index的位移個數幕垦。
? ? 5、增加index的所有計數值
檢索過程
????1先改、先計算key對應的hash值并找到對應的slot
? ? 2疚察、根據slot找到該slot上最新一個index的數據并開始進行回溯
? ? 3、每個index都對比時間戳判斷是否符合要求
? ? 4仇奶、根據每個index的前置index來獲取前一個index的值