都存什么
- commitLog文件
- consumeQueue文件
- indexFile文件
- 報錯文件等等
存在哪
存在每個broker的磁盤中
commitLog文件
是什么藐翎?
消息真正存儲的地方柬批。消息發(fā)送到broker的時候。先存儲到commitLog飞崖,broker存儲到commitLog后就通知producer消息發(fā)送成功了。commitLog到consmeQueue是broker的分發(fā)策略去做的谨胞。
存儲結構
存在 rocketmq/store/commitlog文件夾中固歪。
以offset為文件名,存儲message胯努。
每個文件默認都是1G牢裳。一個文件寫滿后术瓮,創(chuàng)建另外一個文件,以該文件的第一個message的偏移量命名贰健。文件名20位胞四,不夠補0。
因為伶椿。message的大泄嘉啊(長度)是固定的,所以可以通過offset快速找到文件脊另,再通過長度快速找到這條消息导狡。這里和數(shù)組很像,存數(shù)組頭的地址信息偎痛,后面尋址旱捧,直接用數(shù)組頭+偏移量直接就能找到。
commitLog不是永久落盤的踩麦。默認存活時間是72小時枚赡,超過72小時,就標記為失效文件谓谦,默認每天凌晨4點清除失效文件贫橙。
是直接落盤么
肯定不是啊。中間有一層buffer(NIO內(nèi)存映射問文件)
MapperFileQueue相當于commitlog這個文件夾
MapperFile相當于commitlog文件夾下的每個文件
消息發(fā)送到后反粥,先存在這個內(nèi)存變量中卢肃,根據(jù)刷磁盤策略,往磁盤中刷數(shù)據(jù)才顿。也就是刷臟頁莫湘。
刷臟頁策略:
- 同步:寫入buffer,馬上刷臟頁郑气,然后再返回producer消息發(fā)送成功幅垮。這樣,能防止發(fā)送階段消息不丟失竣贪。
- 異步:寫入buffer军洼,就返回producer消息發(fā)送成功。然后根據(jù)broker的刷臟頁策略來刷臟頁演怎。
異步刷臟頁策略
rocketMq有兩個參數(shù)去控制
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 30
vm.dirty_writeback_centisecs = 500
vm.dirty_background_ratio = 10
當臟頁數(shù)量達到系統(tǒng)內(nèi)存10%時就會觸發(fā)pdflush/flush/kdmflush等后臺進程匕争,將一部分緩存的臟頁異步的刷進磁盤。
vm.dirty_ratio = 30
當臟頁數(shù)量達到系統(tǒng)內(nèi)存30%時爷耀,系統(tǒng)開始同步的將臟頁刷入磁盤甘桑,同時會阻塞其他進程的寫操作。
10/30是系統(tǒng)默認值,可以自己根據(jù)業(yè)務情況設置跑杭。
寫的過程是什么
因為存在一個地方(commitLog)铆帽,所以消息必須要順序寫。每次寫請求進入后德谅,先拿寫鎖爹橱,阻塞順序寫。
consumeQueue文件
是什么
這個是真正的mq的隊列窄做。里面不存具體的消息愧驱,而是存消息的指針。這個指針指向commitlog中該消息的位置椭盏。
這樣做的好處是:
1组砚、擴展性好。消息的真是數(shù)據(jù)存在一個地方掏颊,不會根據(jù)queue的變動而變動糟红。
2、查詢速度快乌叶。
存儲結構
第一層是topic盆偿。
第二層是topic下queue隊列id。
第三層是隊列下的消息文件枉昏。
單個ConsumerQueue文件中默認包含30萬個條目陈肛,單個文件的長度為30W * 20字節(jié)。
commitlog在向consumerQueue轉發(fā)的時候兄裂,會根據(jù)producer中的send策略,判斷轉發(fā)到哪個隊列中阳藻。
策略包括:輪訓晰奖、隨機、key hash腥泥。
怎么查找
consumeQueue可以理解為寫隊列匾南。
針對于查找還會有一個讀隊列processQueue。
每個消費者group蛔外,都會有隔離的一組隊列蛆楞,通過processQueue做到的每個group的隔離。
消費者根據(jù) offset和tag拉consumerQueue的數(shù)據(jù) 到 processQueue夹厌,最終消費的是processQueue豹爹。processQueue是每個組隔離的。
indexFile索引文件
是什么
是commitLog的索引文件矛纹。與queue隊列無關臂聋。單純的commitLog以key為索引的索引文件。
slot table存的是key的hash值。也就是后面index的索引孩等。有hash沖突怎么辦艾君,這里就不是鏈表法了,用的是二次hash來解決hash沖突肄方。
index linked list: 存的是具體的索引冰垄。
index linked list: 存的是具體的索引。
key hash: message key的hash值
phyOffset: message在commitlog的物理文件地址权她,可以直接查詢到該消息(存儲的核心機制)
timeDiff:message的落盤時間與header里的beginTimestamp的差值(為了節(jié)省存儲空間虹茶,如果直接存message的落盤時間就得8bytes)
prevIndex: hash沖突處理的關鍵之處,相同hash值上一個消息索引的index(如果當前消息索引是該hash值的第一個索引伴奥,則prevIndex=0, 也是消息索引查找時的停止條件写烤。)