RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

阿里云云栖号發表於2024-04-24

前言:

從初代開源訊息佇列崛起,到 PC 網際網路、移動網際網路爆發式發展,再到如今 IoT、雲端計算、雲原生引領了新的技術趨勢,訊息中介軟體的發展已經走過了 30 多個年頭。

目前,訊息中介軟體在國內許多行業的關鍵應用中扮演著至關重要的角色。隨著數字化轉型的深入,客戶在使用訊息技術的過程中往往同時涉及交叉場景,比如同時進行物聯網訊息、微服務訊息的處理,同時進行應用整合、資料整合、實時分析等,企業需要為此維護多套訊息系統,付出更多的資源成本和學習成本。

在這樣的背景下,2022 年,RocketMQ 5.0 正式釋出,相對於 RocketMQ 4.0,架構走向雲原生化,並且覆蓋了更多的業務場景。

物聯網訊息場景

我們先來了解一下物聯網的場景是什麼?訊息在物聯網裡面有什麼作用?

物聯網肯定是最近幾年最火的技術趨勢之一,有大量的研究機構、行業報告都提出了物聯網快速發展的態勢:

首先,物聯網裝置規模爆發式增長,預測會在 2025 年達到 200 多億臺。

其次,物聯網的資料規模快速增長,來自物聯網的資料增速接近 28%,並且未來有 90% 以上的實時資料來自物聯網場景。這也就意味著未來的實時流資料處理的資料型別會有大量物聯網資料。

最後,邊緣計算是一個重要的趨勢,未來會有 75% 的資料在傳統資料中心或者雲環境之外來處理,這裡的邊緣指的是商店、工廠、火車等等這些離資料來源更近的地方。由於物聯網產生的資料規模很大,如果全部資料傳輸到雲端處理,會面臨難以承受的成本,應該充分利用邊緣資源直接計算,再把高價值的計算結果傳輸雲端;另一方面,在離使用者近的地方計算直接響應,可以降低延遲,提升使用者體驗。

物聯網的發展速度這麼快,資料規模那麼大,跟訊息有什麼關係呢?

我們透過這個圖來看一下訊息在物聯網場景發揮的作用:

第一個作用是連線,承擔通訊的職責,支援裝置和裝置的通訊,裝置和雲端應用的通訊,比如感測器資料上報、雲端指令下發等場景,作為支撐 IoT 的應用架構,連線雲邊端。

第二個作用是資料處理,物聯網裝置源源不斷的產生資料流,有大量需要實時流處理的場景,比如裝置維護,高溫預警等等。基於 MQ 的事件流儲存和流計算能力,可以構建物聯網場景的資料架構。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

物聯網訊息技術

下面我們來看看在物聯網場景裡,對訊息技術有什麼訴求?

我們先從這個表格來對比,物聯網訊息技術跟之前講過的經典訊息技術的區別。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

經典的訊息主要是為服務端系統提供釋出訂閱的能力,而物聯網的訊息技術是為物聯網裝置之間、裝置和服務端之間提供釋出訂閱的能力。

我們來分別看一下各自場景的特點:

  • 經典訊息場景:訊息 Broker、訊息客戶端都作為服務端系統的一部分,通常部署在 IDC 或者公共雲環境中配置效能較高的伺服器上,包括容器、虛擬機器、物理機等形式。訊息客戶端和服務端通常部署在同一個機房,內網環境具有高頻寬和穩定的網路質量。客戶端數量通常與應用伺服器數量相對應,規模較小,一般是數百到數千臺伺服器,只有超大型網際網路公司才會達到百萬級。從訊息生產的角度來看,每個客戶端的訊息生產傳送量一般對應到其業務的 TPS,能達到數百數千 TPS。在訊息消費方面,通常採用叢集消費,一個應用叢集共享一個消費者 ID,共同分擔該消費組的訊息。每條訊息的訂閱比通常也不高,正常情況下不會超過 10 個。
  • IoT 訊息場景:很多條件都與經典訊息場景不一樣,甚至截然相反。IoT 的訊息客戶端通常是微型裝置,其計算和儲存資源都非常有限。訊息服務端可能要部署在邊緣環境中,使用的伺服器配置也會比較低。另一方面,物聯網裝置通常透過公網連線,網路環境特別複雜,並且由於裝置經常移動,有時會面臨斷網或處於弱網環境,網路質量差且不穩定。物聯網場景中,訊息客戶端例項數對應到物聯網裝置數,可能達到億級別,遠遠超過大型網際網路公司的伺服器數量。儘管每個裝置的訊息 TPS 不高,但是一條訊息有可能同時被百萬個裝置接收,訂閱位元別高。

RocketMQ - MQTT

由此可以看出,物聯網需要的訊息技術和經典的訊息技術很不一樣。接下來我們再來看,為了應對物聯網的訊息場景,RocketMQ 5.0 做了哪些事情?

RocketMQ 5.0 我們釋出了一個子產品,叫做 RocketMQ - MQTT。

它有三個技術特點:

第一,它採用標準的物聯網協議 MQTT,該協議面向物聯網弱網環境、低算力的特點設計,協議十分精簡。它還提供豐富的特性,支援多種訂閱模式,多種訊息 QoS,比如“最多一次”、“最少一次”和“當且僅當一次”。其領域模型設計也是基於“訊息、主題、釋出訂閱”等概念,與 RocketMQ 高度相容,為構建一個雲端一體化的 RocketMQ 產品形態奠定了堅實的基礎。

第二,它採用存算分離的架構。RocketMQ Broker 作為儲存層,MQTT 相關的領域邏輯都在 MQTT Proxy 層實現,並面向海量連線、訂閱關係、實時推送進行深度最佳化,Proxy 層可以根據物聯網業務負載提供獨立的彈性擴充套件,例如增加連線數只需新增 Proxy 節點。

第三,它採用端雲一體化的架構。因為領域模型接近,並且以 RocketMQ 作為儲存層,每條訊息只需儲存一份,這份訊息既能被物聯網裝置消費,也能被雲端應用消費。另外,RocketMQ 本身是天然的流儲存,流計算引擎可以無縫對 IoT 資料進行實時分析。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

接下來我們再從幾個關鍵的技術點,來深入瞭解 RocketMQ 的物聯網技術實現。

(一)IoT 訊息儲存模型

1. 讀放大為主,寫放大為輔

首先要解決的是物聯網訊息的儲存模型,在釋出訂閱的業務模型裡,一般會採用兩種儲存模型,一種是讀放大,每條訊息只寫到一個公共佇列,所有消費者讀取這個共享佇列,維護自己的消費位點;另外一種是寫放大,每個消費者有自己的佇列,每條訊息都分發到目標消費者的佇列中,消費者只讀自己的佇列。

因為在物聯網場景裡,一條訊息可能會有百萬級的裝置消費,所以,很顯然,選擇讀放大的模型能顯著降低儲存成本、提高效能。

但是,只選擇讀放大的模式沒法完全滿足要求,MQTT 協議有其特殊性,它的 Topic 是多級 Topic,且訂閱方式既有精準訂閱,也有萬用字元匹配訂閱。比如家居場景,我們定義一個多級主題,如“家/浴室/溫度”,有直接訂閱完整多級主題的“家/浴室/溫度”,也有采用萬用字元訂閱只關注“溫度”的,還有隻關注一級主題為“家”的所有訊息。

對於直接訂閱完整的多級主題消費者可以採用讀放大的方式直接讀取對應多級主題的公共佇列;而採用萬用字元訂閱的消費者無法反推訊息的 Topic,所以需要在訊息儲存時根據萬用字元的訂閱關係多寫一個萬用字元佇列,這樣消費者就可以根據其訂閱的萬用字元佇列讀取訊息。這就是 RocketMQ 採用的讀放大為主,寫放大為輔的儲存模型。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

2. 端雲一體化儲存

基於前文的分析,我們設計了 RocketMQ 端雲一體化的儲存模型,見下圖。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

訊息可以來自各個接入場景(如服務端的 RMQ/AMQP,裝置端的 MQTT),但只會寫一份存到 Commitlog 裡面,然後分發出多個需求場景的佇列索引,比如服務端場景(MQ/AMQP)可以按照一級 Topic 佇列進行傳統的服務端消費,裝置端場景可以按照 MQTT 多級 Topic 以及萬用字元訂閱進行消費訊息。這樣我們就可以基於同一套儲存引擎,同時支援服務端應用整合和 IoT 場景的訊息收發,達到端雲一體化。

(二)佇列規模問題

我們都知道像 Kafka 這樣的訊息佇列每個 Topic 是獨立檔案,但是隨著 Topic 增多,訊息檔案數量也增多,順序寫就退化成了隨機寫,效能明顯下降。RocketMQ 在 Kafka 的基礎上進行了改進,使用了一個 Commitlog 檔案來儲存所有的訊息內容,再使用 CQ 索引檔案來表示每個 Topic 裡面的訊息佇列,因為 CQ 索引資料比較小,檔案增多對 IO 影響要小很多,所以在佇列數量上可以達到十萬級。但是,這個終端裝置佇列的場景下,十萬級的佇列數量還是太小了,我們希望進一步提升一個數量級,達到百萬級佇列數量,所以,我們引入了 Rocksdb 引擎來進行 CQ 索引分發。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

面向 IoT 的百萬級佇列設計

Rocksdb 是一個廣泛使用的單機 KV 儲存引擎,有高效能的順序寫能力。因為我們有了 Commitlog 已具備了訊息順序流儲存,所以可以去掉 Rocksdb 引擎裡面的 WAL,基於 Rocksdb 來儲存 CQ 索引。在分發的時候,我們使用了 Rocksdb 的 WriteBatch 原子特性,分發時把當前的 MaxPhyOffset 注入進去,因為 Rocksdb 能夠保證原子儲存,後續可以根據這個 MaxPhyOffset 來做 Recover 的 checkpoint。最後,我們也提供了一個 Compaction 的自定義實現,來進行 PhyOffset 的確認,以清理已刪除的髒資料。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

(三)IoT 訊息推送模型

介紹了底層的佇列儲存模型後,我們再詳細描述一下上層的訊息實時推送(匹配查詢和可靠觸達)是怎麼做的?

在 RocketMQ 的經典消費模式裡,消費者是直接採用長輪詢的方式,從客戶端直接發起請求,精確讀取對應的 Topic 佇列。而在 MQTT 場景裡,因為客戶端數量、訂閱關係數量規模巨大,無法採用原來的長輪詢模式,消費鏈路的實現更加複雜,所以,這裡採用的是推拉結合的模型。

下圖展示的是一個推拉模型,物聯網終端裝置透過 MQTT 協議連到 Proxy 節點。訊息從服務端(MQ/AMQP/MQTT)傳送過來,存到 Topic 佇列後,會有一個 notify 邏輯模組來實時感知這個新訊息到達,然後會生成訊息事件(就是訊息的 Topic 名稱),把這個事件推送至 Proxy 節點,Proxy 節點根據它連上的終端裝置訂閱情況進行內部匹配,找到哪些終端裝置能匹配上,然後會觸發 pull 請求去儲存層讀取訊息,再推送到終端裝置。

一個重要問題,就是訂閱關係的匹配查詢。一般有兩種方式:第一種,簡單的廣播事件;第二種,集中儲存線上訂閱關係(比如圖裡的 lookup 模組),然後進行匹配查詢,再精準推送。

事件廣播機制看起來有擴充套件性問題,但是其實效能並不差,因為我們推送的資料很小,就是 Topic 名稱,而且相同 Topic 的訊息事件可以攢批推送,RocketMQ 5.0 就是預設採用的這個方式。集中儲存線上訂閱關係,這個也是常見的一種做法,如儲存到 RDS、Redis 等等,但要保證資料的實時一致性也是有難度的,而且要進行匹配查詢對整個訊息的實時鏈路 RT 開銷也會有一定的影響。下圖模型中可以看到,在 Proxy 節點還會引入一個 Cache 模組,用來做訊息佇列 Cache,避免在廣播場景下每個終端裝置都向儲存層發起讀資料的情況。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

總結

本文分三個部分深入探討了 RocketMQ 5.0 關於物聯網訊息技術的應用與最佳化,第一部分概述一個典型的物聯網技術架構,並重點闡述訊息佇列在此架構中的關鍵作用。第二部分,探討了物聯網場景對訊息技術的特殊要求,並分析這些要求與服務端應用中的訊息技術之間的差異。第三部分,深入介紹了 RocketMQ 5.0 的 MQTT 子產品,闡釋其如何有效應對物聯網領域的技術挑戰。旨在為大家提供一個全面的視角,理解訊息佇列在物聯網中的重要性及其解決方案。

RocketMQ 之 IoT 訊息解析:物聯網需要什麼樣的訊息技術?

作者:林清山(隆基)

原文連結

本文為阿里雲原創內容,未經允許不得轉載。

相關文章