後端程序員必備:RocketMQ相關流程圖/原理圖

前言

整理了一些RocketMQ相關流程圖/原理圖,作一下筆記,你們一塊兒學習。html

RocketMQ是什麼

  • 是一個隊列模型的消息中間件,具備高性能、高可靠、高實時、分佈式特色。
  • Producer、Consumer、隊列均可以分佈式。
  • Producer 向一些隊列輪流發送消息,隊列集合稱爲 Topic,Consumer 若是作廣播消費,則一個 consumer 實例消費這個 Topic 對應的全部隊列,若是作集羣消費,則多個 Consumer 實例平均消費這個 topic 對應的隊列集合。
  • 可以保證嚴格的消息順序
  • 提供豐富的消息拉取模式
  • 高效的訂閱者水平擴展能力
  • 實時的消息訂閱機制
  • 億級消息堆積能力
  • 較少的依賴

RocketMQ 核心組件圖

RocketMQ是開源的消息中間件,它主要由NameServer,Producer,Broker,Consumer四部分構成。 java

NameServer

NameServer主要負責Topic和路由信息的管理,功能相似Dubbo的zookeeper。數組

Producer

消息生產者,負責產生消息,通常由業務系統負責產生消息。緩存

Broker

消息中轉角色,負責存儲消息,轉發消息。服務器

Consumer

消息消費者,負責消息消費,通常是後臺系統負責異步消費。數據結構

RokcetMQ 物理部署圖

NameServer

NameServer是一個幾乎無狀態節點,可集羣部署,節點之間無任何信息同步。架構

Broker

Broker分爲Master與Slave,一個Master能夠對應多個Slave,可是一個Slave只能對應一個Master,Master與Slave的對應關係經過指定相同的BrokerName,不一樣的BrokerId來定義,BrokerId爲0表示Master,非0表示Slave。Master也能夠部署多個。每一個Broker與Name Server集羣中的全部節點創建長鏈接,定時註冊Topic信息到全部Name Server。app

Producer

Producer與Name Server集羣中的其中一個節點(隨機選擇)創建長鏈接,按期從Name Server取Topic路由信息,並向提供Topic服務的Master創建長鏈接,且定時向Master發送心跳。Producer徹底無狀態,可集羣部署。運維

Consumer

Consumer與Name Server集羣中的其中一個節點(隨機選擇)創建長鏈接,按期從Name Server取Topic路由信息,並向提供Topic服務的Master、Slave創建長鏈接,且定時向Master、Slave發送心跳。Consumer既能夠從Master訂閱消息,也能夠從Slave訂閱消息,訂閱規則由Broker配置決定。異步

RocketMQ 邏輯部署結構

Producer Group

用來表示一個發送消息應用,一個 Producer Group 下包含多個 Producer 實例,能夠是多臺機器,也能夠 是一臺機器的多個進程,或者一個進程的多個 Producer 對象。一個 Producer Group 能夠發送多個 Topic 消息,Producer Group 做用以下:

  • 標識一類 Producer
  • 能夠經過運維工具查詢這個發送消息應用下有多個 Producer 實例
  • 發送分佈式事務消息時,若是 Producer 中途意外宕機,Broker 會主動回調 Producer Group 內的任意 一臺機器來確認事務狀態。

Consumer Group

用來表示一個消費消息應用,一個 Consumer Group 下包含多個 Consumer 實例,能夠是多臺機器,也可 以是多個進程,或者是一個進程的多個 Consumer 對象。一個 Consumer Group 下的多個 Consumer 以均攤 方式消費消息,若是設置爲廣播方式,那麼這個 Consumer Group 下的每一個實例都消費全量數據。

NameServer 路由註冊、刪除機制

  • Broker每30秒向NameServer發送心跳包,心跳包中包含topic的路由信息
  • NarneServer 收到 Broker 心跳包後 更新 brokerLiveTable 中的信息, 特別記錄心跳時間 lastUpdateTime
  • NarneServer 每隔 10s 掃描 brokerLiveTable, 檢 測表中上次收到心跳包的時間,比較當前時間 與上一次時間,若是超過120s,則認爲 broker 不可用,移除路由表中與該 broker相關的全部 信息
  • 消息生產者拉取主題的路由信息,即消息生產者並不會當即感知 Broker 服務器的新增與刪除。

RocketMQ的消息領域模型圖

Topic

  • Topic表示消息的第一級類型,好比一個電商系統的消息能夠分爲:交易消息、物流消息等。一條消息必須有一個Topic。
  • 最細粒度的訂閱單位,一個Group能夠訂閱多個Topic的消息。

Tag

Tag表示消息的第二級類型,好比交易消息又能夠分爲:交易建立消息,交易完成消息等。RocketMQ提供2級消息分類,方便靈活控制。

Group

組,一個組能夠訂閱多個Topic。

Message Queue

消息的物理管理單位。一個Topic下能夠有多個Queue,Queue的引入使得消息的存儲能夠分佈式集羣化,具備了水平擴展能力。

在 RocketMQ 中,全部消息隊列都是持久化,長度無限的數據結構,所謂長度無限是指隊列中的每一個存儲單元都是定長,訪問其中的存儲單元使用 Offset 來訪問,offset 爲 java long 類型,64 位,理論上在 100年內不會溢出,因此認爲是長度無限。

也能夠認爲 Message Queue 是一個長度無限的數組,Offset 就是下標。

順序消息原理圖

消費消息的順序要同發送消息的順序一致,在 RocketMQ 中,主要的是局部順序,即一類消息爲知足順 序性,必須 Producer 單線程順序發送,且發送到同一個隊列,這樣 Consumer 就能夠按照 Producer 收送 的順序去消費消息。

RocketMQ 消息存儲設計原理圖

CommitLog

消息存儲文件,全部消息主題的消息都存儲在 CommitLog 文件中。 Commitlog 文件存儲的邏輯視圖如圖所示

ConsumeQueue

消息消費隊列,消息到達 CommitLog 文件後,將異步轉發到消息 消費隊列,供消息消費者消費。ConsumeQueue存儲格式以下:

  • 單個 ConsumeQueue 文件中默認包含 30 萬個條目,單個文件的長度爲 30w × 20 字節, 單個 ConsumeQueue 文件能夠看出是一個 ConsumeQueue 條目的數組,其下標爲 ConsumeQueue 的邏輯偏移量,消息消費進度存儲的偏移量 即邏輯偏移量。
  • ConsumeQueue 即爲 Commitlog 文件的索引文件, 其構建機制是當消息到達 Commitlog 文件後, 由專門的線程 產生消息轉發任務,從而構建消息消費隊列文件與下文提到的索引文件。

IndexFile

消息索引文件,主要存儲消息 Key 與 Offset 的對應關係。

消息消費隊列是RocketMQ專門爲消息訂閱構建的索引文件,提升根據主題與消息隊 列檢索消息的速度 ,另外 RocketMQ 引入了 Hash 索引機制爲消息創建索引, HashMap 的設 計包含兩個基本點 : Hash 槽與 Hash 衝突的鏈表結構。 RocketMQ 索引文件佈局如圖所示

lndexFile 總共包含 lndexHeader、 Hash 槽、 Hash 條目

事務狀態服務

存儲每條消息的事務狀態。

定時消息服務

每個延遲級別對應一個消息消費隊列,存儲延遲隊列的消息拉取進度。

RMQ文件存儲模型層

RocketMQ業務處理器層

Broker端對消息進行讀取和寫入的業務邏輯入口,這一層主要包含了業務邏輯相關處理操做(根據解析RemotingCommand中的RequestCode來區分具體的業務操做類型,進而執行不一樣的業務處理流程),好比前置的檢查和校驗步驟、構造MessageExtBrokerInner對象、decode反序列化、構造Response返回對象等。

RocketMQ數據存儲組件層

  • 該層主要是RocketMQ的存儲核心類—DefaultMessageStore,其爲RocketMQ消息數據文件的訪問入口,經過該類的「putMessage()」和「getMessage()」方法完成對CommitLog消息存儲的日誌數據文件進行讀寫操做(具體的讀寫訪問操做仍是依賴下一層中CommitLog對象模型提供的方法);
  • 另外,在該組件初始化時候,還會啓動不少存儲相關的後臺服務線程,包括AllocateMappedFileService(MappedFile預分配服務線程)、ReputMessageService(回放存儲消息服務線程)、HAService(Broker主從同步高可用服務線程)、StoreStatsService(消息存儲統計服務線程)、IndexService(索引文件服務線程)等。

RocketMQ存儲邏輯對象層

  • 該層主要包含了RocketMQ數據文件存儲直接相關的三個模型類IndexFile、ConsumerQueue和CommitLog。
  • IndexFile爲索引數據文件提供訪問服務,ConsumerQueue爲邏輯消息隊列提供訪問服務,CommitLog則爲消息存儲的日誌數據文件提供訪問服務。
  • 這三個模型類也是構成了RocketMQ存儲層的總體結構。

封裝的文件內存映射層

  • RocketMQ主要採用JDK NIO中的MappedByteBuffer和FileChannel兩種方式完成數據文件的讀寫。
  • 其中,採用MappedByteBuffer這種內存映射磁盤文件的方式完成對大文件的讀寫,在RocketMQ中將該類封裝成MappedFile類。
  • 這裏,每一種類的單個文件均由MappedFile類提供讀寫操做服務(其中,MappedFile類提供了順序寫/隨機讀、內存數據刷盤、內存清理等和文件相關的服務)。

磁盤存儲層

主要指的是部署RocketMQ服務器所用的磁盤。這裏,須要考慮不一樣磁盤類型(如SSD或者普通的HDD)特性以及磁盤的性能參數(如IOPS、吞吐量和訪問時延等指標)對順序寫/隨機讀操做帶來的影響。

RocketMQ中消息刷盤

在RocketMQ中消息刷盤主要能夠分爲同步刷盤和異步刷盤兩種。

同步刷盤

  • 在返回寫成功狀態時,消息已經被寫入磁盤。
  • 具體流程是,消息寫入內存的PAGECACHE後,馬上通知刷盤線程刷盤,而後等待刷盤完成,刷盤線程執行完成後喚醒等待的線程,返回消息寫成功的狀態。
  • 通常只用於金融場景。

異步刷盤

在返回寫成功狀態時,消息可能只是被寫入了內存的PAGECACHE,寫操做的返回快,吞吐量大;當內存裏的消息量積累到必定程度時,統一觸發寫磁盤操做,快速寫入。

消息在系統中流轉圖

1.Producer 發送消息,消息從 socket 進入 java 堆。

2.Producer 發送消息,消息從 java 堆轉入 PAGACACHE,物理內存。

3.Producer 發送消息,由異步線程刷盤,消息從 PAGECACHE 刷入磁盤。

4.Consumer 拉消息(正常消費),消息直接從 PAGECACHE(數據在物理內存)轉入 socket,到達 consumer, 不通過 java 堆。這種消費場景最多,線上 96G 物理內存,按照 1K 消息算,能夠在物理內存緩存 1 億條消 息。

5.Consumer 拉消息(異常消費),消息直接從 PAGECACHE(數據在虛擬內存)轉入 socket。

6.Consumer 拉消息(異常消費),因爲 Socket 訪問了虛擬內存,產生缺頁中斷,此時會產生磁盤 IO,從磁 盤 Load 消息到 PAGECACHE,而後直接從 socket 發出去。

7.同 5 一致。

8.同 6 一致。

參考與感謝

我的公衆號

歡迎你們關注,你們一塊兒學習,一塊兒討論。

相關文章
相關標籤/搜索