1. 程式人生 > >探祕 RocketMQ 訊息持久化機制

探祕 RocketMQ 訊息持久化機制

我們知道 RocketMQ 是一款高效能、高可靠的分散式訊息中介軟體,高效能和高可靠是很難兼得的。因為要保證高可靠,那麼資料就必須持久化到磁碟上,將資料持久化到磁碟,那麼可能就不能保證高效能了。

RocketMQ 在相容這兩方面做的不錯,先從磁碟說起,現代的磁碟都是高效能的,寫速度並不一定比網路的資料傳輸速度慢。比如 SSD 固態硬碟在 M.2 NVMe協議下,順序寫的速度可以達到 1500 MB/s,就算是普通磁碟,如果效能比較高的話,順序寫的速度可以達到 450MB/s~600MB/s。

在順序寫的情況下是這速度,但是不人為控制的話,磁碟採用的是隨機寫,在隨機寫的情況下,磁碟的寫入速度急速下降,磁碟的隨機寫速度可能只有幾百KB/s,這遠遠要慢於網路傳輸速度,所以它並不能滿足高效能的要求。

RocketMQ 在持久化的設計上,採取的是訊息順序寫、隨機讀的策略,利用磁碟順序寫的速度,讓磁碟的寫速度不會成為系統的瓶頸。並且採用 MMPP 這種“零拷貝”技術,提高訊息存檔和網路傳送的速度。極力滿足 RocketMQ 的高效能、高可靠要求。

上述從硬體的角度聊聊了高效能的保證,這些咱也不懂,還是來看看 RocketMQ 持久化機制的架構圖吧。

在 RocketMQ 持久化機制中,涉及到了三個角色:

  • CommitLog:訊息真正的儲存檔案,所有訊息都儲存在 CommitLog 檔案中。
  • ConsumeQueue:訊息消費邏輯佇列,類似資料庫的索引檔案。
  • IndexFile:訊息索引檔案,主要儲存訊息 Key 與 offset 對應關係,提升訊息檢索速度。

咱們逐一聊聊吧,CommitLog 檔案是存放訊息資料的地方,所有的訊息都將存入到 CommitLog 檔案中。生產者將訊息傳送到 RocketMQ 的 Broker 後,Broker 伺服器會將訊息順序寫入到 CommitLog 檔案中,這也就是 RocketMQ 高效能的原因,因為我們知道磁碟順序寫特別快,RocketMQ 充分利用了這一點,極大的提高訊息寫入效率。

但是消費者消費訊息的時候,可能就會遇到麻煩,每一個消費者只能訂閱一個主題,消費者關心的是訂閱主題下的所有訊息,但是同一主題的訊息在 CommitLog 檔案中可能是不連續的,那麼消費者消費訊息的時候,需要將 CommitLog 檔案載入到記憶體中遍歷查詢訂閱主題下的訊息,頻繁的 IO 操作,效能就會急速下降。

為了解決這個問題,RocketMQ 引入了 Consumequeue 檔案。Consumequeue 檔案可以看作是索引檔案,類似於 MySQL 中的二級索引。在存放了同一主題下的所有訊息,消費者消費的時候只需要去對應的 Consumequeue 組中取訊息即可。Consumequeue 檔案不會儲存訊息的全量資訊,瞭解 MySQL 索引的話,應該好理解這裡,具體儲存的欄位,我在上圖已經標註。這樣做可以帶來以下兩個好處:

  • 由於 Consumequeue 檔案內容小,可以儘可能的保證 Consumequeue 檔案全部讀入到記憶體,提高消費效率。
  • Consumequeue 檔案也是會持久化的,不存全量資訊可以節約磁碟空間。

IndexFile 是 RocketMQ 為訊息訂閱構建的索引檔案,用來提高根據主題與訊息佇列檢索訊息的速度,這個就不細說了。

RocketMQ 持久化機制原理差不多就這些了,接下來聊一聊訊息資料刷盤吧。

因為作業系統 PAGECACHE 的存在,PageCache是OS對檔案的快取,用於加速對檔案的讀寫,所以一般都是先寫入到 PAGECACHE 中,然後再持久化到磁碟上。我們熟悉的其他元件,MySQL、Redis 等都是如此。RocketMQ 也不列外。

在 RocketMQ 中提供了同步刷盤和非同步刷盤兩種刷盤方式,可以通過 Broker 配置文中中的 flushDiskType 引數來設定(SYNC_FLUSH、ASYNC_FLUSH)。

非同步刷盤方式(預設):訊息寫入到記憶體的 PAGECACHE中,就立刻給客戶端返回寫操作成功,當 PAGECACHE 中的訊息積累到一定的量時,觸發一次寫操作,將 PAGECACHE 中的訊息寫入到磁碟中。這種方式吞吐量大,效能高,但是 PAGECACHE 中的資料可能丟失,不能保證資料絕對的安全。

同步刷盤方式:訊息寫入記憶體的 PAGECACHE 後,立刻通知刷盤執行緒刷盤,然後等待刷盤完成,刷盤執行緒執行完成後喚醒等待的執行緒,返回訊息寫成功的狀態。這種方式可以保證資料絕對安全,但是吞吐量不大。

關於RocketMQ 持久化機制的分享就這些,感謝您的閱讀,希望這篇文章對您的學習或者工作有一點幫助。有收穫的話,也可以幫忙推薦給其他的小夥伴,讓更多的人受益,萬分感謝。

歡迎關注公眾號【網際網路平頭哥】。這裡有職場感悟、Java 技術,雖然不高大上,但通俗易懂。今天最好的是明天最低的要求,願你我共同進步。

相關推薦

探祕 RocketMQ 訊息持久化機制

我們知道 RocketMQ 是一款高效能、高可靠的分散式訊息中介軟體,高效能和高可靠是很難兼得的。因為要保證高可靠,那麼資料就必須持久化到磁碟上,將資料持久化到磁碟,那麼可能就不能保證高效能了。 RocketMQ 在相容這兩方面做的不錯,先從磁碟說起,現代的磁碟都是高效能的,寫速度並不一定比網路的資料傳輸速度

ActiveMQ的幾種訊息持久化機制

為了避免意外宕機以後丟失資訊,需要做到重啟後可以恢復訊息佇列,訊息系統一般都會採用持久化機制。 ActiveMQ的訊息持久化機制有JDBC,AMQ,KahaDB和LevelDB四種方式,無論使用哪種持久化方式,訊息的儲存邏輯都是一致的。 就是在傳送者將訊息傳送出

ActiveMQ的JDBC訊息持久化機制

為了避免意外宕機以後丟失資訊,需要做到重啟後可以恢復訊息佇列,訊息系統一般都會採用持久化機制。 ActiveMQ的訊息持久化機制有JDBC,AMQ,KahaDB和LevelDB,無論使用哪種持久化方式,訊息的儲存邏輯都是一致的。 就是在傳送者將訊息傳送出去後,訊息中心

Rocketmq訊息持久化

本文編寫,參考:https://my.oschina.net/bieber/blog/725646producer Send()的Message最終將由broker處理,處理類為:SendMessageProcessor ,處理方法:processRequet.public class SendMessage

RabbitMQ 訊息持久化、事務、Publisher的訊息確認機制

RabbitMQ  訊息持久化、事務、Publisher的訊息確認機制 1. 宣告MessageQueue 在RabbitMQ中,無論是生產者傳送訊息還是消費者接受訊息,都首先需要宣告一個MessageQueue。 這就存在一個問題,是生產者宣告還是消費者宣告呢?要解決這個

RocketMQ原理(4)——訊息ACK機制及消費進度管理

https://zhuanlan.zhihu.com/p/25265380 consumer的每個例項是靠佇列分配來決定如何消費訊息的。那麼消費進度具體是如何管理的,又是如何保證訊息成功消費的(RocketMQ有保證訊息肯定消費成功的特性(失敗則重試)? 本文將詳細解

原始碼分析RocketMQ訊息ACK機制(消費進度)

首先簡要闡述一下訊息消費進度首先消費者訂閱訊息消費佇列(MessageQueue),當生產者將訊息負載傳送到MessageQueue中時,消費訂閱者開始消費訊息,訊息消費過程中,為了避免重複消費,需要一

RocketMQ原始碼學習】- 5. 訊息儲存機制

前言 面試官:你瞭解RocketMQ是如何儲存訊息的嗎?我:額,,,你等下,我看下這篇文字, (逃 由於這部分內容優點多,所以請哥哥姐姐們自備茶水,歡迎留言!   RocketMQ儲存設計是高可用和高效能的保證, 利用磁碟儲存來滿足海量堆積能力。Kafka單機在topic數量在100+的時候,效能會

RocketMQ重試機制訊息冪等

一、重試機制   由於MQ經常處於複雜的分散式系統中,考慮網路波動,服務宕機,程式異常因素,很有可能出現訊息傳送或者消費失敗的問題。因此,訊息的重試就是所有MQ中介軟體必須考慮到的一個關鍵點。如果沒有訊息重試,就可能產生訊息丟失的問題,可能對系統產生很大的影響。所以,秉承寧可多發訊息,也不可丟失訊息的原則,大

細說Redis持久化機制

pac 文件太大 rdb redis持久化 三種方式 server tracking 場景 自己的 概述 Redis不僅能夠作為緩存來使用,也能夠作為內存數據庫。Redis作為內存數據庫使用時。必需要解決一個問題:數據的持久性。有些將Redis作為緩存使用的場

redis高級命令4 持久化機制 、事務

丟失 1-1 數據 生成 開啟 緩存 字符 set 我們 redis的事務是支持很簡單,基本沒有啥用我們來看下面的列子 我們開啟一個事務,在事務中執行了age 加1,set a4 ,還有對一個字符串進行加一,對字符串加1導致了事務失敗,按道理incr age在事務操作

redis的持久化機制

執行 末尾 redis服務器 請求 阻塞 aof文件 就是 而不是 自動 redis簡介   redis是一個基於內存的nosql數據庫,和傳統關系數據最大的區別就是數據是存在內存中而不是硬盤上,從而帶來了tps的巨大提升。但是基於內存的數據庫最大的缺陷就是機器斷電

Redis的持久化機制包括RBD和AOF兩種,對於這兩種持久化方式各有優勢

plain 同步數據 pen toc 默認 ocl 好的 dfs 操作系統 RDB機制的策略 RDB持久化是指在指定的時間間隔內將內存中的數據和操作通過快照的方式保存到redis bin目錄下的一個默認名為 dump.rdb的文件,可以通過配置設置自動的快照持久化的

redis持久化機制

toolbar 我們 等等 HERE 了解 OS row alt 數據 redis持久化機制 參考: https://www.cnblogs.com/xingzc/p/5988080.html https://blog.csdn.net/yujin2010good/

MFC訊息對映機制的理解

當窗體,控制元件,點選標題欄等時,會產生訊息,然後發給訊息處理函式進行處理,而訊息與訊息對映表是一一對應的關係,這個關係就是訊息對映表,根據根據訊息通過訊息對映表來查詢對應的訊息處理函式,這就稱為訊息對映機制。 而Windows有自己的訊息佇列,通過訊息迴圈,採用GetMessage來獲取訊

android 非同步訊息處理機制 — AHandler

1. 引入 ALooper、AHandler、AMessage 在 android multimedia stagefright 的框架程式碼中,通篇都是這幾個類的身影,所以熟悉 android 多媒體框架的第一步必須理解這幾個類的含義。 這幾個類是為了實現非同步訊息機制而設計的

Android核心技術-day04-01-網路圖片檢視器(安卓訊息迴圈機制)

package com.gaozewen.netimageviewer; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import and

Redis學習之持久化機制

原文部落格地址: pjmike的部落格 前言 持久化就是將Redis記憶體中的資料寫入到磁碟中進行儲存,因為Redis是記憶體資料庫,資料都是存在記憶體中的,為了避免程序退出導致資料的丟失,所以需要將資料持久化到硬碟中,這樣下次Redis重啟後可以利用之前持久化的檔案實現資料恢復。 一般有兩種

activemq實戰之訊息持久化

對於activemq訊息的持久化我們在第二節的時候就簡單介紹過,今天我們詳細的來分析一下activemq的持久化過程以及持久化外掛。在生產環境中為確保訊息的可靠性,我們肯定的面臨持久化訊息的問題,今天就一起來攻克他吧。 1. 持久化方式介紹 前面我們也簡單提

JMS訊息可靠機制

ActiveMQ訊息簽收機制: 客戶端成功接收一條訊息的標誌是一條訊息被簽收,成功應答。 訊息的簽收情形分兩種: 1、帶事務的session    如果session帶有事務,並且事務成功提交,則訊息被自動簽收。如果事務回滾,則訊息會被再次傳送。 2、不帶事務的sess