學(xué)習(xí)文檔:
1.RocketMQ高性能之底層存儲設(shè)計(jì) https://juejin.cn/post/6844903728521166856
2.https://www.cnblogs.com/duanxz/p/5020398.html
3.http://www.itdecent.cn/p/e0befd11aee0
核心問題
對RocketMq整體存儲架構(gòu)設(shè)計(jì)的認(rèn)知
RocketMQ文件布局

CommitLog和ConsumeQueue

CommitLog
一個文件集合,每個文件1G大小,存儲滿后存下一個,為了討論方便可以把它當(dāng)成一個文件,所有消息內(nèi)容全部持久化到這個文件中;因?yàn)槭侨罩臼降拇鎯?,基本都是順序?qū)懀?/p>
ConsumeQueue
消息消費(fèi)的邏輯隊(duì)列,作為消費(fèi)消息的索引,保存了指定Topic下的隊(duì)列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。而IndexFile(索引文件)則只是為了消息查詢提供了一種通過key或時(shí)間區(qū)間來查詢消息的方法(ps:這種通過IndexFile來查找消息的方法不影響發(fā)送與消費(fèi)消息的主流程)。從實(shí)際物理存儲來說,ConsumeQueue對應(yīng)每個Topic和QueuId下面的文件。單個文件大小約5.72M,每個文件由30W條數(shù)據(jù)組成,每個文件默認(rèn)大小為600萬個字節(jié),當(dāng)一個ConsumeQueue類型的文件寫滿了,則寫入下一個文件;
IndexFile
因?yàn)樗械南⒍即嬖贑ommitLog中,如果要實(shí)現(xiàn)根據(jù) key 查詢 消息的方法,就會變得非常困難,所以為了解決這種業(yè)務(wù)需求,有了IndexFile的存在。用于為生成的索引文件提供訪問服務(wù),通過消息Key值查詢消息真正的實(shí)體內(nèi)容。在實(shí)際的物理存儲上,文件名則是以創(chuàng)建時(shí)的時(shí)間戳命名的,固定的單個IndexFile文件大小約為400M,一個IndexFile可以保存 2000W個索引;
Mapped文件
可以直接將對于內(nèi)存的操作寫在PageCache;而非需要多次copy
整體存儲流程


整體看出RocketMQ的存儲設(shè)計(jì)比較簡單
元數(shù)據(jù)存儲在CommitLog里,通過CommitLog創(chuàng)建ConsumeQueue和IndexFile文件(兩個文件都是索引)
ConsumeQueue用于構(gòu)建內(nèi)存中隊(duì)列用于消費(fèi),支持按照時(shí)間查詢消息(二分搜索)
IndexFile就是提供MsgKey或MsgId查詢的功能
HashSlot就是對應(yīng)每一個Hash值的鏈表的表頭,Index則是每個鏈表的節(jié)點(diǎn)
首先根據(jù)MsgKey或許MsgId算出HashSlot,然后利用HashSlot來找到鏈表表頭,不斷遍歷找到對應(yīng)的節(jié)點(diǎn)