亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

引言

對于一款消息中間件來說,優良的數據存儲設計,是實現高性能消息吞吐以及消息查詢的關鍵所在。因為消息中間件對于外部來說就是發消息消費消息的一個平臺基礎設施,但是從其本身來說,需要將海量消息數據信息持久化在 RocketMQ 節點所在的服務器上,這樣即便是服務器斷電,重啟等情況下,也不至于丟失消息數據。另外在進行消息消費的時候,RocketMQ 如何能借助自身的存儲設計快速檢索到對應的消息也是非常重要的,因此本文主要對 RocketMQ 存儲設計進行了設計分析。

存儲結構

RocketMQ 對應的存儲文件主要包括三類,分別是 Commitlog 文件、ConsumeQueue 文件以及 Index 文件,每一個文件都有其特殊的使命。

 

Commitlog 文件

當生產者將消息發送到 RocketMQ 的 Broker 之后,需要將消息進行持久化存儲,防止消息數據丟失。RocketMQ 將消息數據寫入存儲文件 CommitLog 中,按照消息的發送順序寫入文件當中,每個文件的大小約為 1G,當達到文件大小限制后,就會創建新的 CommitLog 文件。RocketMQ 作為消息中間件來說,最主要的數據流程就是基于主題的發布-訂閱模式進行消息的發布以及消費,那么當消費者根據自己訂閱的 Topic 進行消息消費的時候,Broker 怎么在那么多的 CommitLog 文件中找到對應 Topic 的消息數據呢?

 

大家可以想一想,CommitLog 文件中的消息數據是一條一條順序寫的,最笨的方法就是遍歷文件,作為一款高性能的消息中間件,顯然這不是一個好的解決方案。就像從數據庫查詢數據的時候,遍歷的效率肯定是很低的。那么我們可不可以借助數據庫提升數據查詢的方式,使用索引來加快消息數據的查詢呢?答案是肯定的。就像 MySQL 中的索引本身需要文件保存一樣,在 RocketMQ 中頁有單獨保存索引的文件,就是 ConsumerQueue 文件。

ConsumerQueue 文件

在 RocketMQ 中,每個 Topic 對應多個 MessageQueue,每個 MessageQueue 對應一組 ConsumerQueue 文件索引文件。ConsumerQueue 文件中存儲了消息相對于 CommitLog 文件的 offset 偏移量,CommitLog 文件本身實際上也是通過偏移量來進行命名如第一個文件是 0000000000000,那么第二文件就是消息總量之和 00000001232321,往后新的文件再進行累計。為什么這么做呢?主要就是在進行消息查找的時候根據消息的偏移量通過二分查找快速定位具體的 CommitLog 文件,提升消息查找效率。需要說明的是,Broker 在進行消息寫入 CommitLog 文件中就會異步將其對應的偏移量寫入 ConsumerQueue 文件中。

 

在 ConsumerQueue 文件中實際存儲了 CommitLog 文件的 offset 偏移量、消息長度以及 tag 的 hashcode,組成 20 字節的 block 塊。其在 Broker 上面的存儲路徑大致是:…/store/consumequeue/{topic}/{queueid}/{file}。其中 topic 就是生產中訂閱的主題,因此消費者在消費消息的時候,Broker 會根據其對應的 Topic 找到對應的 ConsumerQueue 文件,進而找到其索引位置,再到 CommitLog 文件中直接定位具體的消息。

Index 文件

另外 RocketMQ 的特性功能就是可以實現按照消息的屬性進行消息搜索,即建立了索引 Key 的 hashcode 與物理偏移量的映射關系,根據 key 先快速定義到 commitlog 文件。

 

存儲性能設計精髓

上文中為大家闡述了 RocketMQ 關于存儲結構的設計,優秀的存儲設計師實現高性能讀寫的前提。那么除了存儲結構的設計,RocketMQ 也使用了一些性能優化手段來實現其強大的消息吞吐能力。

消息順序寫

前文中說過,消息進入 RocketMQ 之后,消息數據是通過順序寫的方式落到 CommitLog 文件中的。那么這里面就涉及兩個問題,為什么進行順序寫以及是不是直接寫磁盤文件。

1、為什么要順序寫?

當新的數據到來時,只要在之前的文件末尾進行數據追加就可以,這樣的數據寫入效率要比隨機寫入的效率高。

2、每次數據寫入的時候是直接寫磁盤文件嗎?

我們可以反過想,如果每次都是落盤寫入的話實際效率是不高的,無法滿足消息中間件這種高吞吐的性能要求,因此 RocketMQ 實際是借助操作系統的 page cache 來提升寫入效率的,消息并不是直接寫入磁盤,認識先寫入操作系統的 page cache,然后再通過異步刷盤的方式,寫入 CommitLog 文件中,這樣借助順序寫以及系統的 page cache 可以時間近乎內存的數據寫入效率。

同步刷盤和異步刷盤

剛才所說的異步寫入,其實就是 RocketMQ 的異步刷盤模式,但是大家想想這個模式有沒有什么問題。為了提升數據吞吐量,消息數據過來后,并沒有直接寫盤,而是在系統中的 page cache 中。那么此時如果 Broker 宕機了,那么此時的消息數據是容易丟失的。所以雖然異步刷盤的寫入效率高但是也存在數據丟失的風險。

1、同步刷盤

在同步刷盤的場景下,當 Broker 接受到對應的消息之后,Broker 將會把這條消息刷入磁盤的 CommitLog 中,才會返回確認消息給生產者。如果在進行消息寫入的時候 Broker 掛了,那么生產者會感受到消息投遞失敗,一般都會都有消息重新發送的重試邏輯。

這樣看消息似乎不會丟失了,但是由于每次都是先落盤,就會導致數據寫入性能下降。

MMAP

在 RocketMQ 中使用了 mmap 技術來實現 Conmmitlog 文件的高性能讀寫,mmap 就是一種內存映射文件的方法,對于傳統的文件 IO 交互來說,需要經過多次的數據復制過程才能將用戶進程的數據寫入硬盤或者讀入程序。而 mmap 可以直接將虛擬內存中的文件與硬盤中文件地址進行映射,減少了數據拷貝的過程,從而提升了數據寫入的效率。關于這部分的內容可以參見以前的文章有詳細的介紹。

總結

本文主要堆 RocketMQ 的存儲設計進行了分析,圍繞如何實現高性能消息寫入和查詢展開了闡述,希望在分析這些優秀中間的具體實現過程中,我們可以將這些優秀設計融入到具體的項目實踐中,當我們遇到類似的問題的時候可以借助于這些設計思想來解決實際的問題。

分享到:
標簽:RocketMQ
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定