<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
RocketMQ有Producer、Consumer、NameSrv、Broker四個部分。其中Broker用於儲存訊息,維護訊息佇列和訂閱關係,是RocketMQ四個部分中最重要的一個部分,並且RocketMQ的高效能就是依賴於Broker模組的底層儲存模型實現的。所以搞清楚Broker的儲存模型是學習RocketMQ最重要的一步。
RocketMQ 優異的效能表現,必然繞不開其優秀的儲存模型 。
這篇文章,筆者按照自己的理解 , 嘗試分析 RocketMQ 的儲存模型,希望對大家有所啟發。
首先溫習下 RocketMQ 架構。
整體架構中包含四種角色 :
本文的重點在於分析 BrokerServer 的訊息儲存模型。我們先進入 broker 的檔案儲存目錄 。
訊息儲存和下面三個檔案關係非常緊密:
訊息主體以及後設資料的儲存主體 ;
訊息消費佇列,引入的目的主要是提高訊息消費的效能 ;
索引檔案,提供了一種可以通過 key 或時間區間來查詢訊息。
RocketMQ 採用的是混合型的儲存結構,Broker 單個範例下所有的佇列共用一個資料檔案(commitlog)來儲存。
生產者傳送訊息至 Broker 端,然後 Broker 端使用同步或者非同步的方式對訊息刷盤持久化,儲存至 commitlog 檔案中。只要訊息被刷盤持久化至磁碟檔案 commitlog 中,那麼生產者傳送的訊息就不會丟失。
Broker 端的後臺服務執行緒會不停地分發請求並非同步構建 consumequeue(消費檔案)和 indexFile(索引檔案)。
RocketMQ 的訊息資料都會寫入到資料檔案中, 我們稱之為 commitlog 。
所有的訊息都會順序寫入資料檔案,當檔案寫滿了,會寫入下一個檔案。
如上圖所示,單個檔案大小預設 1G , 檔名長度為 20 位,左邊補零,剩餘為起始偏移量,比如 00000000000000000000 代表了第一個檔案,起始偏移量為 0 ,檔案大小為1 G = 1073741824。
當第一個檔案寫滿了,第二個檔案為 00000000001073741824,起始偏移量為 1073741824,以此類推。
從上圖中,我們可以看到訊息是一條一條寫入到檔案,每條訊息的格式是固定的。
這樣設計有三點優勢:
磁碟的存取速度相對記憶體來講並不快,一次磁碟 IO 的耗時主要取決於:尋道時間和碟片旋轉時間,提高磁碟 IO 效能最有效的方法就是:減少隨機 IO,增加順序 IO 。
《 The Pathologies of Big Data 》這篇文章指出:記憶體隨機讀寫的速度遠遠低於磁碟順序讀寫的速度。磁碟順序寫入速度可以達到幾百兆/s,而隨機寫入速度只有幾百 KB /s,相差上千倍。
因為訊息是一條一條寫入到 commitlog 檔案 ,寫入完成後,我們可以得到這條訊息的物理偏移量。
每條訊息的物理偏移量是唯一的, commitlog 檔名是遞增的,可以根據訊息的物理偏移量通過二分查詢,定位訊息位於那個檔案中,並獲取到訊息實體資料。
訊息 offsetMsgId 是由 Broker 伺服器端在寫入訊息時生成的 ,該訊息包含兩個部分:
我們可以通過訊息 offsetMsgId ,定位到 Broker 的 ip 地址 + 埠 ,傳遞物理偏移量引數 ,即可定位該訊息實體資料。
在介紹 consumequeue 檔案之前, 我們先溫習下訊息佇列的傳輸模型-釋出訂閱模型 , 這也是 RocketMQ 當前的傳輸模型。
釋出訂閱模型具有如下特點:
因此,rocketmq 的檔案設計必須滿足釋出訂閱模型的需求。
那麼僅僅 commitlog 檔案是否可以滿足需求嗎 ?
假如有一個 consumerGroup 消費者,訂閱主題 my-mac-topic ,因為 commitlog 包含所有的訊息資料,查詢該主題下的訊息資料,需要遍歷資料檔案 commitlog , 這樣的效率是極其低下的。
進入 rocketmq 儲存目錄,顯示見下圖:
每個 consumequeue 包含 30 萬個條目,每個條目大小是 20 個位元組,每個檔案的大小是 30 萬 * 20 = 60萬位元組,每個檔案大小約5.72M 。和 commitlog 檔案類似,consumequeue 檔案的名稱也是以偏移量來命名的,可以通過訊息的邏輯偏移量定位訊息位於哪一個檔案裡。
消費檔案按照主題-佇列來儲存 ,這種方式特別適配發布訂閱模型。
消費者從 broker 獲取訂閱訊息資料時,不用遍歷整個 commitlog 檔案,只需要根據邏輯偏移量從 consumequeue 檔案查詢訊息偏移量 , 最後通過定位到 commitlog 檔案, 獲取真正的訊息資料。
這樣就可以簡化消費查詢邏輯,同時因為同一主題下,消費者可以訂閱不同的佇列或者 tag ,同時提高了系統的可延伸性。
每個訊息在業務層面的唯一標識碼要設定到 keys 欄位,方便將來定位訊息丟失問題。伺服器會為每個訊息建立索引(雜湊索引),應用可以通過 topic、key 來查詢這條訊息內容,以及訊息被誰消費。
由於是雜湊索引,請務必保證key儘可能唯一,這樣可以避免潛在的雜湊衝突。
//訂單Id String orderId = "1234567890"; message.setKeys(orderId);
從開源的控制檯中根據主題和 key 查詢訊息列表:
進入索引檔案目錄 ,如下圖所以:
索引檔名 fileName 是以建立時的時間戳命名的,固定的單個 IndexFile 檔案大小約為 400 M 。
IndexFile 的檔案邏輯結構類似於 JDK 的 HashMap 的陣列加連結串列結構。
索引檔案主要由 Header、Slot Table (預設 500 萬個條目)、Index Linked List(預設最多包含 2000萬個條目)三部分組成 。
假如訂單系統傳送兩條訊息 A 和 B , 他們的 key 都是 "1234567890" ,我們依次儲存訊息 A , 訊息 B 。
因為這兩個訊息的 key 的 hash 值相同,它們對應的雜湊槽(深黃色)也會相同,雜湊槽會儲存的最新的訊息 B 的索引條目序號 , 序號值是 4 ,也就是第二個深綠色條目。
而訊息 B 的索引條目資訊的最後 4 個位元組會儲存上一條訊息對應的索引條目序號,索引序號值是 3 , 也就是訊息 A 。
Databases are specializing – the “one size fits all” approach no longer applies ------ MongoDB設計哲學
RocketMQ 儲存模型設計得非常精巧,筆者覺得每種設計都有其底層思考,這裡總結了三點 :
到此這篇關於終於弄明白了 RocketMQ 的儲存模型的文章就介紹到這了,更多相關 RocketMQ 儲存模型內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45