天天看點

有關 EMQ X 水準可擴充性的挑戰與對策 - MQTT Broker 叢集詳解(三)

在這篇文章中,我們将介紹 MQTT Broker 叢集在可擴充性方面的一些改進。 我們将主要關注 EMQ X 内部使用的資料庫引擎,以及它在 EMQ X 5.0 版本中是如何改進的。

在開始本文之前,我們需要了解 EMQ X 叢集中是資料是如何複制的:EMQ X broker 将主題和用戶端的運作時資訊存儲在 Mnesia 資料庫中,有助于跨叢集複制資料。

Mnesia 是一個開源資料庫管理系統,由愛立信公司開發作為開放電信平台( Open Telecom Platform )的一部分,最初是用來處理 ISP 級電信交換機中的配置和運作時資料。EMQ X 4.3 之前的版本使用其來存儲各種運作時資料,例如主題、路由、ACL 規則、告警等等。

MySQL、Postgres、MongoDB 等資料庫以及 Redis 和 memcached 等記憶體存儲大家應該都非常熟悉,對 Mnesia 則可能不甚了解。但它确實有其獨特的優勢,可将上述産品的許多功能內建到一個簡潔的應用程式中。

Mnesia 有一個相當學術的定義:一個嵌入式、分布式、事務型的 noSQL(非關系型)資料庫。聽起來有些複雜,我們接下來将逐一為大家解釋。

MySQL 和 Postgres 等最廣泛使用的資料庫普遍采用用戶端—伺服器模式:資料庫在單獨的程序中運作(通常在專用伺服器上),業務應用程式通過網絡或 UNIX 域套接字發送請求并等待答複,通過這種方式來與資料庫互動。這種模式在很多方面都很友善,因為它允許将業務邏輯與存儲分開并單獨管理。 但同時也有一些缺點:與遠端程序互動不可避免地會增加每個請求的延遲。

相反,嵌入式資料庫與業務應用程式則在相同的程序中運作。sqlite 是一個典型的嵌入式資料庫的例子。Mnesia 也屬于這一類:它與其他 EMQ X 應用程式在同一程序中運作。 從 Mnesia 表中讀取資料可以像讀取局部變量一樣快,是以我們可以在熱點中讀取資料庫資料而不會影響性能。

我們之前提到過 Mnesia 是一個分布式資料庫,這意味着資料表被網絡複制到不同的實體位置。對于分布式資料庫,如果節點之間不共享任何實體資源(如 RAM 或磁盤),而是在應用程式級别進行協調,這種類型稱為無共享架構 (SN)。 這種類型通常是首選,因為它不需要任何專門的硬體,并且可以水準擴充。

Mnesia 應用程式與 EMQ X 一起運作,有助于通過 Erlang 分發協定跨叢集中的所有節點複制表更新。 這意味着業務應用程式可以在本地讀取更新的資料。它還有助于提升容錯性能:隻要叢集中有一個節點處于活動狀态,資料就是安全的。EMQ X 依靠此功能實作跨叢集複制路由資訊。

Mnesia 支援 ACID 事務,這是嵌入式資料庫的一個非常獨特的功能。這意味着可以将多個讀取和更新操作組合在一起。一個 Mnesia 事務具有原子性(必須完整或無任何效力)、一緻性(盡管保證比 Postgres 更寬松)、隔離性(不影響其他事務)和持久性。所有這些保證都在整個叢集中保留。

在資料一緻性關鍵場景中,EMQ X 采用 Mnesia 事務。

傳統的關系型資料庫使用一種稱為 SQL 的特殊查詢語言與資料庫進行互動,這種資料庫通常使用 ORM(對象關系映射) 來加快開發速度。 另一方面,Mnesia 沒有專門的查詢語言:它使用 Erlang(或 Elixir)作為查詢語言,是以不需要 ORM。 它直接使用 Erlang 術語進行查詢操作,與業務邏輯的內建非常順暢。

在 Mnesia 叢集中,所有節點都是平等的。 每個節點都可以存儲任何表的副本、啟動事務并通路這些表。 Mnesia 叢集使用全網狀拓撲:每個節點都與叢集中的所有其他節點對話。 每個事務都被複制到叢集中的所有節點,如下圖所示:

有關 EMQ X 水準可擴充性的挑戰與對策 - MQTT Broker 叢集詳解(三)

針對 CAP 原則(在一緻性、可用性、分區容錯性三個要素中選擇兩個),Mnesia 預設為 AP(可用性、分區容錯性)。

綜上所述,Mnesia 資料庫有一系列獨特的功能,并都在 EMQ X 中得到了使用。現在,我們要談談它的缺點以及我們改進它的原因。

盡管 Mnesia 與硬體無關,但它最初的開發考慮了特定的叢集架構:一組伺服器,通過快速、低延遲的區域網路實作互連。

在理想條件下,網狀拓撲結構可以減少事務複制延遲:節點之間的所有通信都可以并行完成,無需任何中介。 然而,它限制了叢集的水準可擴充性,因為節點之間的連結數量和節點數量之間是平方關系。随着節點數量的增加,保持所有節點完全同步的成本越來越高,事務的性能也會下降。

節點的同等性質和傳統的叢集範式疊加後,使得更換單個節點變得容易,但是可以同時加入叢集的節點數量受到限制。

于是我們就面臨這樣一個局面:叢集部署在地理備援的雲環境中,一切都是動态的和暫時的,節點在自動擴充組中運作,我們希望它們一直在波動狀态。

為了應對這些挑戰,我們對 Mnesia 進行了擴充,稱之為 Mria。

Mria 是 Mnesia 的開源擴充版本,它為 Mnesia 帶來了最終一緻性。

Mria 從全網狀拓撲架構轉變為網狀+星型拓撲架構。 每個節點承擔兩個角色之一:核心(core)或複制者(replicant)。

核心(core)節點的行為很像正常的 Mnesia 節點:它們以全網狀連接配接,每個節點都可以發起寫事務、持有鎖等。核心節點很大程度上都是靜态和持久的。

另一方面,複制(replicant)節點不參與事務。它們連接配接到某一個核心節點,并被動地從中複制事務。這意味着不允許複制節點自行執行任何寫操作。相反,它們要求核心節點代表它們更新資料。同時,它們擁有資料的完整本地副本,是以讀取通路速度也同樣快。

有關 EMQ X 水準可擴充性的挑戰與對策 - MQTT Broker 叢集詳解(三)

可以将 Mria 看作是用戶端-伺服器和嵌入式資料庫的組合:通過伺服器寫入,但在本地讀取。

這種叢集拓撲架構解決了兩個問題:

水準可擴充性

支援叢集自動擴充

由于複制節點不參與寫入,是以當向叢集添加更多複制節點時,事務延遲不會受到影響,進而允許建立更大的 EMQ X 叢集。

此外,複制節點被設計為暫時的。 添加或删除它們不會改變資料備援,是以可以将它們放在自動擴充組中,進而實作更好的 DevOps 實踐。

在下一篇文章中,我們将更詳細地讨論如何配置 EMQ X 來充分 Mria 的優勢。

MQTT Broker 叢集詳解(一):負載均衡

MQTT Broker 叢集詳解(二):粘性會話負載均衡

版權聲明: 本文為 EMQ 原創,轉載請注明出處。 原文連結:https://www.emqx.com/zh/blog/mqtt-broker-clustering-part-3-challenges-and-solutions-of-emqx-horizontal-scalability 技術支援:如對本文或 EMQ 相關産品有疑問,可通路 EMQ 問答社群 https://askemq.com 提問,我們将會及時回複支援。 更多技術幹貨,歡迎關注我們公衆号【EMQ 中文社群】。

繼續閱讀