EMQX クラスタリング
EMQX クラスタリングとは、複数の EMQX ノードが連携して統一されたシステムとして動作するデプロイメントを指します。これらのノードはクライアントのセッション、トピックのサブスクリプション、およびルーティング情報を自動的に共有し、シームレスなメッセージ配信と水平スケーラビリティを実現します。
Note
クラスタリング機能はトライアル期間中に利用可能です。トライアル終了後は商用ライセンスが必要であり、ライセンスがない場合は機能が無効化されます。
本章では、クラスタリングの利点、新しいMria と RLOGアーキテクチャ、クラスタの手動および自動作成方法、ロードバランシングの実装方法、およびクラスタ内の通信セキュリティ確保について紹介します。
このアーキテクチャは、MQTT を基盤とした大規模かつミッションクリティカルな IoT およびメッセージングプラットフォームに最適です。
章のプレビュー
本章では、EMQX クラスタリングの包括的な概要と実際のデプロイメントへの適用方法を解説します。以下の内容を学べます:
- クラスタリングの利点
- EMQX クラスタリングの動作原理
- Mria と RLOG アーキテクチャ
- クラスタの手動および自動作成方法
- ノード間通信のセキュリティ確保
- ロードバランシングの実装方法
- クラスタ負荷のリバランスとノードの退避
- システムチューニングとパフォーマンステスト
高可用性の MQTT プラットフォーム構築や本番規模への準備に役立つガイドです。
なぜ EMQX クラスタリングを使うのか
EMQX クラスタリングは、信頼性、スケーラビリティ、パフォーマンスを求められる大規模かつミッションクリティカルなアプリケーション向けに設計されています。主な利点は以下の通りです:
- スケーラビリティ:ノードを追加することで容易にデプロイメントを拡張でき、EMQX は増加する MQTT クライアントとメッセージをサービス停止なく処理可能です。
- 高可用性:分散アーキテクチャにより単一障害点がなく、1つ以上のノードがオフラインになってもシステムは継続稼働します。
- ロードバランシング:MQTT トラフィックとクライアントセッションをノード間で分散し、ボトルネックを防ぎハードウェア利用率を最大化します。
- 集中管理:すべてのノードは単一のダッシュボードや API エンドポイントから管理・監視でき、運用と保守が簡素化されます。
- データの一貫性とセキュリティ:セッションとルーティング状態はノード間で自動的に複製され、一貫性を保ちつつクラスタ全体で安全な通信を維持します。
EMQX クラスタリングの動作原理
EMQX クラスターは複数のノードで構成され、それぞれが EMQX のインスタンスを実行しています。これらのノードは連携してメッセージのルーティング、MQTT セッションの管理、高可用性とスケーラビリティの確保を行います。各ノードは他のノードと通信し、クライアントのサブスクリプションやルーティング情報を共有することで、クライアントがどのノードに接続していても関連するサブスクライバーにメッセージが届くようにします。
この分散設計により、EMQX は最小限のダウンタイムでミッションクリティカルなメッセージングシステムをサポートし、柔軟な拡張が可能です。
クラスタアーキテクチャの進化
EMQX 5.0 以前:Mnesia ベースのクラスタリング
初期の EMQX は Erlang/OTP の組み込みデータベース Mnesia とフルメッシュトポロジーを使用していました。各ノードは Erlang 分散プロトコル(デフォルトポート:4370)を介してすべての他ノードと直接 TCP 接続を維持し、密結合のシステムを形成していました。

しかし、このモデルには以下の制約がありました:
- クラスタサイズ増加に伴う高い同期オーバーヘッド
- 5 ノード以上のクラスタでの不安定性リスク
- スケーラビリティの制限(主に垂直スケーリングで対応)
EMQX 4.3 はベンチマークテストで 1000 万同時接続を達成しましたが、これには大幅なチューニングと高性能ハードウェアが必要でした。詳細はパフォーマンスレポートを参照してください。
EMQX 5.0 以降:Mria + RLOG
バージョン 5.0 からは、新しいMria クラスタアーキテクチャが導入され、より大規模かつ安定したクラスタをサポートしています。
主な変更点は以下の通りです:
- Core ノードと Replicant ノードの役割分担:Core ノードは書き込みと完全なデータ複製を担当し、Replicant ノードは読み取り専用でクライアントセッションを処理します。
- レプリケーションログ(RLOG):Core から Replicant への非同期かつ高スループットなデータ複製を可能にします。
- スケーラビリティ:クラスタあたり最大 1 億 MQTT 接続をサポートします。

Note
厳密な上限はありませんが、EMQX のオープンソース版ではクラスタサイズを 3 ノードに制限することを推奨します。Core タイプのノードのみを使用した小規模クラスタの方が安定性が高い傾向にあります。
このアーキテクチャを支えるために、EMQX は Erlang/OTP とルーティングおよび配信のための内部データ構造群を利用しています。Erlang/OTP の基礎およびクラスタデータ構造のセクションで、ランタイムの基盤とこれらの構造のクラスタ内での動作を解説します。
Erlang/OTP の基礎
EMQX は分散型通信システム構築のために設計されたランタイムおよびフレームワークであるErlang/OTP上に構築されています。Erlang では各ランタイムインスタンスをノードと呼び、<name>@<host> 形式の名前で識別します。例:emqx1@192.168.0.10。
Erlang ノードは TCP 経由で接続し、軽量なメッセージパッシングで通信します。これが EMQX クラスタリングの基盤となっています。各ノードは同じ cookie を用いて認証を行う必要があり、接続と認証が完了するとノードは自動的に EMQX クラスタに参加します。EMQX 5.x 以降では、ノードの役割(Core または Replicant)がデータ複製やルーティングへの参加方法を決定します。
クラスタデータ構造
分散クラスタ内で効率的にメッセージをルーティングするために、EMQX はサブスクリプションテーブル、ルーティングテーブル、トピックツリーという3つの主要な内部データ構造を使用しています。これらは連携して、クライアントが複数ノードに分散していてもメッセージを正しくサブスクライバーに届けることを保証します。
サブスクリプションテーブル(パーティション化)
各 EMQX ノードはローカルのサブスクリプションテーブルを保持し、MQTT トピックとそのノードに直接接続しているクライアントをマッピングしています。データはパーティション化されており、各ノードは自分のクライアントのサブスクリプションのみを保存するため、オーバーヘッドが減りスケーラビリティが向上します。
メッセージがノードにルーティングされると、そのノードはサブスクリプションテーブルを参照して、どのローカルクライアントにメッセージを配信すべきか判断します。
例:
node1:
topic1 -> client1, client2
topic2 -> client3
node2:
topic1 -> client4この例は、同じトピック (topic1) に複数ノードでサブスクライバーが存在しつつ、各ノードが独自のローカルマッピングを管理していることを示しています。
ルーティングテーブル(Core から複製)
ルーティングテーブルは、どのトピックがどのノードでサブスクライブされているかを追跡します。EMQX 5.x ではこのテーブルは Core ノードのみが管理・複製し、Replicant ノードは RLOG メカニズムを通じて読み取り専用コピーを受け取ります。
クライアントが任意のノード(通常は Replicant)でトピックをサブスクライブすると、そのサブスクリプションイベントは Core ノードに転送され、クラスタ全体のルーティングテーブルが更新・複製されます。
例:
topic1 -> node1, node2
topic2 -> node3
topic3 -> node2, node4トピックツリー(Core から複製)
トピックツリーは階層構造で、パブリッシュされたトピックとサブスクリプションパターン(MQTT ワイルドカードの + や # を含む)をマッチングするために使われます。これにより EMQX は複雑なトピックフィルターを高速に解決できます。
ルーティングテーブルと同様に、トピックツリーは Core ノードによって複製され、Replicant ノードと共有されます。新しいサブスクリプション(例:client1 が t/+/x をサブスクライブ)を受けると、トピックツリーは全ノードで更新されます。更新処理は Core ノードが担当し、その後複製されます。
トピックとサブスクリプションの例:
| クライアント | ノード | サブスクライブ中のトピック |
|---|---|---|
| client1 | node1 | t/+/x, t/+/y |
| client2 | node2 | t/# |
| client3 | node3 | t/+/x, t/a |
これらのサブスクリプションが設定されると、EMQX は以下のトピックツリーとルーティングテーブルを構築します。

メッセージ配信フロー
MQTT クライアントがメッセージをパブリッシュすると、接続先ノード(Core または Replicant)はトピックツリーを使ってメッセージのトピックをすべてのサブスクリプションパターンと照合します。次にルーティングテーブルを参照し、マッチするサブスクライバーがいるノードを特定してメッセージを転送します(複数ノードに送信される場合もあります)。受信した各ノードはローカルのサブスクリプションテーブルを参照し、該当するサブスクライバーにメッセージを配信します。
例えば、クライアント 1 がトピック t/a にメッセージをパブリッシュした場合のルーティングと配信の流れは次の通りです:
クライアント 1 は ノード 1 に接続し、トピック
t/aのメッセージをパブリッシュ。ノード 1 はトピックツリーを参照し、
t/aが既存のサブスクリプションパターンt/aとt/#にマッチすることを確認。ノード 1 はルーティングテーブルを参照し、
- ノード 2 に
t/#をサブスクライブしているクライアントがいる、 - ノード 3 に
t/aをサブスクライブしているクライアントがいる、
ため、メッセージを ノード 2 と ノード 3 の両方に転送。
- ノード 2 に
ノード 2 はメッセージを受信し、ローカルのサブスクリプションテーブルを参照して
t/#をサブスクライブしているクライアントに配信。ノード 3 はメッセージを受信し、ローカルのサブスクリプションテーブルを参照して
t/aをサブスクライブしているクライアントに配信。メッセージ配信処理が完了。
EMQX クラスタリングの動作をより深く理解するには、EMQX クラスタリングの設計を参照してください。
クラスタリング機能の概要
EMQX は、ネイティブの Erlang 分散システムを拡張したEkkaライブラリにより、以下の高度なクラスタリング機能を提供します。これにより、自動ノード検出、動的クラスタ形成、ネットワークパーティション処理、ノードクリーンアップなどが可能になります。
ノード検出と自動クラスタリング
EMQX は複数のノード検出メカニズムをサポートし、多様なデプロイ環境で自動的にクラスタを形成できます:
| 戦略 | 説明 |
|---|---|
manual | コマンドによる手動クラスタ作成 |
static | 静的ノードリストによる自動クラスタリング |
DNS | DNS の A レコードおよび SRV レコードによる自動クラスタリング |
etcd | etcd を利用した自動クラスタリング |
k8s | Kubernetes が提供する自動クラスタリング |
詳細はクラスタの作成と管理を参照してください。
ネットワークパーティションの自動修復
ネットワークパーティション自動修復は、ネットワーク分断からの自動復旧を可能にする EMQX の機能で、ミッションクリティカルなアプリケーションでのダウンタイムを回避します。
この機能は cluster.autoheal 設定で制御され、デフォルトで有効です。
cluster.autoheal = trueこの機能が有効な場合、EMQX はクラスタ内のノード間接続を継続的に監視します。ネットワークパーティションが検出されると、影響を受けたノードを分離し、残りのノードで稼働を継続します。パーティションが解消されると、ブローカーは分離されたノードを自動的にクラスタに再統合します。
パーティション検出と復旧時に生成されるログメッセージやアラームについては、Mria ログとアラームを参照してください。
クラスタノードの自動クリーンアップ
クラスタノード自動クリーンアップ機能は、切断されたノードを設定された時間経過後に自動的にクラスタから削除します。この機能によりクラスタの効率的な稼働が維持され、時間経過によるパフォーマンス低下を防止します。
この機能はデフォルトで有効で、cluster.autoclean 設定(デフォルト:24h)で制御されます。
cluster.autoclean = 24hノード間セッション
EMQX はノード間のセッション永続化をサポートしており、クライアントが一時的に切断されてもセッションとサブスクリプションが保持されます。
この機能を有効にするには:
- MQTT 3.x クライアント:
clean_start = falseを設定 - MQTT 5.0 クライアント:
clean_start = falseおよびsession_expiry_interval > 0を設定
これにより、クライアント切断時にクライアント ID に紐づく以前のセッションデータが保持されます。再接続時に EMQX は前のセッションを再開し、切断中にキューイングされたメッセージを配信し、クライアントのサブスクリプションを維持します。
ネットワーク要件
EMQX クラスタの最適なパフォーマンスを確保するため、ネットワークのレイテンシは 10 ミリ秒未満が望ましいです。レイテンシが 100 ミリ秒を超える場合、クラスタは利用できなくなります。
Core ノードは同一のプライベートネットワーク内に配置する必要があります。Mria+RLOG モードでは、Replicant ノードも同じプライベートネットワークに配置することが推奨されます。
次のステップ:EMQX クラスタの作成
以下のセクションを続けて読み、EMQX クラスタの作成方法を学べます: