Skip to content

MQTT Durable Sessions ​

EMQXにはDurable Sessions機能があり、MQTTセッションとメッセージをディスクに永続的に保存することで、高可用性のレプリカを提供し、データの冗長性と整合性を確保します。セッションの耐久性により、効果的なフェイルオーバーとリカバリ機構を実装でき、サービスの継続性と可用性を保証し、システムの信頼性を向上させます。

本ページでは、EMQXにおけるセッション永続化の概念、原理、および利用方法を紹介します。

基本概念 ​

EMQXのDurable Sessions機能を学ぶ前に、EMQXに関するいくつかの基本概念を理解することが重要です。

セッションと耐久ストレージ ​

セッション:セッションは、EMQX内でクライアント接続ごとに作成される軽量なプロセスです。セッションは、MQTT標準で定められたブローカーの動作(初期接続、トピックのサブスクライブ・サブスクライブ解除、メッセージの配信など)を実装します。

耐久ストレージ(DS):耐久ストレージはEMQX内部のデータベースです。セッションは自身の状態やトピックに送信されたMQTTメッセージを保存するために利用します。耐久ストレージのデータベースエンジンはRocksDBを使用してデータをディスクに保存し、Raftアルゴリズムを用いてクラスター全体でデータを一貫してレプリケートします。耐久ストレージとDurable Sessionsは混同しないように注意してください。

セッション有効期限(Expiry Interval) ​

MQTT標準によれば、クライアントセッションはMQTTブローカー内でクライアント接続と状態の管理を容易にします。Expiry Intervalはセッションのプロパティであり、クライアント接続が終了した後にブローカーがセッション状態を保持する期間を制御します。このプロパティは本ドキュメントの文脈で重要な役割を果たします。

Expiry Intervalが0に設定されたセッションは、クライアントがEMQXに接続している間のみ存在します。クライアントが切断されると、サブスクリプションや未配信メッセージを含むすべてのセッション情報は即座に破棄されます。一方、0以外のExpiry Intervalを持つセッションは、クライアントの接続が終了してもEMQXに保持されます。クライアントがセッション有効期限内に再接続すると、セッションを再開でき、オフライン時にトピックに送信されたメッセージも配信されます。

  • MQTT 5プロトコルを使用するクライアントは、CONNECTまたはDISCONNECTパケットのSession Expiry Intervalプロパティで明示的にセッション有効期限を指定できます。

  • MQTT 3.*プロトコルのクライアントの場合、EMQXは以下のルールでセッション有効期限を決定します。Clean Sessionフラグがtrueの場合はセッション有効期限を0に設定し、そうでなければmqtt.session_expiry_interval設定パラメータの値を使用します。

EMQXにおけるセッション実装 ​

EMQXは用途に応じて最適化された2種類のクライアントセッション実装を提供しています。

  • レギュラーセッション:実行中のEMQXノードのメモリ内に状態を保持するセッション。ノードが再起動すると状態は失われます。
  • Durable Sessions:状態と受信メッセージを耐久ストレージにバックアップするセッション。EMQXノードの再起動後も再開可能です。

セッション実装の選択は、セッション有効期限とdurable_sessions.enable設定パラメータ(グローバルまたはゾーン単位で設定可能)に依存します。以下の基準で実装が選択されます。

durable_sessions.enableセッション有効期限 = 0セッション有効期限 > 0
falseレギュラーレギュラー
trueレギュラーDurable Sessions

EMQXはメッセージの耐久性管理に独自のアプローチを採用しており、レギュラーセッションとDurable Sessionsが共存しつつ、ストレージコストを最小限に抑えています。

セッション実装の比較 ​

クライアントセッションの管理戦略は、サービスの安定性と信頼性を確保する上で重要な要素です。本節では2つのセッション実装の特徴を比較し、それぞれの特性と適用シナリオを理解しやすくし、より適切な導入判断を支援します。

レギュラーセッション ​

この実装はデフォルトであり、EMQX 5.7以前のすべてのリリースで使用されてきました。レギュラーセッションの状態は実行中のEMQXノードのRAMに完全に保持されます。

レギュラーセッションの利点:

  • 非常に高いスループットと低いレイテンシ。
  • クライアントへの即時メッセージ配信。

欠点:

  • セッションをホストするEMQXノードが停止または再起動するとセッションデータが失われる。
  • 未配信メッセージはセッションのメモリキューに保存され、EMQXのメモリ使用量が増加する。
  • メモリ枯渇を防ぐため、EMQXはメモリキューのサイズに制限を設けており、制限を超えると新規メッセージが破棄され、未配信メッセージが失われる可能性がある。

Durable Sessions ​

EMQX v5.7.0で導入されたDurable Sessionsは、セッション状態とDurable Sessionsにルーティングされたメッセージをディスクに保存します。この機能はデフォルトで無効化されており、durable_sessions.enable設定パラメータをtrueに設定することで有効化できます。

Durable Sessionがトピックフィルターをサブスクライブすると、EMQXはそのフィルターにマッチするトピックを「durable」とマークします。これにより、これらのトピックからのMQTT PUBLISHメッセージはレギュラーセッションへのルーティングに加え、messagesと呼ばれる耐久ストレージにも保存されます。

メッセージ配信のプロトコルは、パブリッシャーの耐久性ではなくサブスクライバーのセッション耐久性に依存する点に注意が必要です。

各耐久MQTTメッセージは、サブスクライブしているDurable Sessionsの数や接続状態に関わらず、各レプリカに一度だけ保存されます。これにより効率的なメッセージファンアウトとディスク書き込みの最小化が実現されます。

耐久ストレージは、EMQXクラスター内の複数ノードにセッションメタデータとMQTTメッセージを一貫してレプリケートすることで、高い耐久性と高可用性を提供します。設定可能なレプリケーションファクターにより、各メッセージやセッションのレプリカ数を指定でき、耐久性とパフォーマンスのバランスをユーザーが調整可能です。

Durable Sessionsの利点:

  • EMQXノードの再起動や停止後もセッションを再開できる。
  • MQTTメッセージはメモリキューではなく共有のレプリケートされた耐久ストレージに保存されるため、オンライン・オフラインセッションのRAM使用量が削減される。
  • 未配信メッセージ数に上限がなく、メモリキューのオーバーフローによるメッセージ破棄が発生しない。

欠点:

  • メッセージをディスクに保存するため、システム全体のスループットは低下する。
  • Durable Sessionsはレギュラーセッションよりレイテンシが高い。これはメッセージの書き込み・読み込みがバッチ処理されるためであり、バッチ処理はスループットを向上させる一方で、クライアントがメッセージを受信するまでの遅延(エンドツーエンドのレイテンシ)を増加させる。

Durable Sessionsのクイックスタート ​

本節では、EMQXおよびMQTTクライアントでDurable Sessions機能を素早く利用する方法と、Durable Sessionsの簡単なワークフローを紹介します。

注意

Durable Sessionsを有効化していなくても、ステップ2〜4を実行するとセッションは保持され、メッセージはクライアントキューに保存されます。違いは、ステップ5でノード再起動後にセッションが永続的に保存されるかどうか、復元できるかどうかです。

  1. EMQXでDurable Sessions機能を有効化します。

    デフォルトではDurable Sessionsは無効です。etc/emqx.confファイルを編集し、以下の設定を追加して機能を有効化してください。

    bash
    durable_sessions {
      enable = true
    }

    設定変更後、EMQXを再起動して反映させます。

  2. MQTTクライアントの接続パラメータを調整し、セッション耐久性を有効にします。

    例としてMQTTX CLIを使用します。MQTT 5.0プロトコルがデフォルトのため、--no-cleanオプションを追加してClean Start = falseを設定し、クライアントIDをemqx_cに指定します。EMQXに接続し、t/1トピックをサブスクライブします。

    bash
    mqttx sub -t t/1 -i emqx_c --no-clean -q 1
  3. クライアントを切断し、セッションを保持します。

    ステップ2のクライアントを切断します。EMQXダッシュボードのモニタリング -> クライアントページを開くと、クライアントの状態がDisconnectedのままで、セッションが保持されていることが確認できます。

    MQTT persistent session

  4. クライアントにメッセージを送信し、メッセージがクライアントキューに保存されます。

    再度MQTTX CLIを使用し、benchコマンドで1クライアントからt/1トピックに繰り返しメッセージをパブリッシュします。

    bash
    mqttx bench pub -t t/1 -c 1 -q 1

    MQTTプロトコルに従い、emqx_cクライアントがオフラインでも、サブスクライブしているt/1トピックのメッセージはクライアントキューに保存され、再接続時に配信されます。

  5. EMQXノードを再起動し、セッションとメッセージが耐久ストレージから復元されます。

    EMQXノードを再起動します。クライアント接続操作を行わずにEMQXダッシュボードのモニタリング -> クライアントページを開くと、クライアントの状態がDisconnectedのままで、セッションが復元されていることが分かります。

    同じクライアントID emqx_c と--no-cleanオプションを指定してClean Start = falseでEMQXに接続を試みます。

    bash
    mqttx sub -t t/1 -i emqx_c --no-clean -q 1

    オフライン期間中に受信したメッセージが現在のクライアントに配信されます。

    bash
    ...
    [2024-5-22] [16:14:14] › …  Connecting...
    [2024-5-22] [16:14:14] › ✔  Connected
    [2024-5-22] [16:14:14] › …  Subscribing to t/1...
    [2024-5-22] [16:14:14] › ✔  Subscribed to t/1
    [2024-5-22] [16:14:14] › payload: Hello From MQTTX CLI
    ...

    注意

    • 永続セッションを復元するには、同じクライアントID emqx_c を使用し、--no-cleanオプションでClean Startをfalseに設定する必要があります。この2つの条件を満たす必要があります。
    • 以前のサブスクリプション情報はセッションに保存されているため、再接続時にt/1トピックを再度サブスクライブしなくてもメッセージは配信されます。

耐久ストレージのアーキテクチャ ​

Durable Sessionsはセッション状態とメッセージの永続化に耐久ストレージを利用しています。このストレージ層の構造と動作を理解するには、Design for Durable Storageの「Architecture: Backends and Storage Hierarchy」セクションを参照してください。

耐久ストレージがDurable Sessionsおよび共有サブスクリプションセッションをサポートする仕組み ​

耐久ストレージはEMQXにおけるDurable Sessionsと共有サブスクリプションセッションの基盤です。

Durable Sessions ​

Durable SessionsはDSデータベースエンジン上に実装されています。クライアントが非ゼロのセッション有効期限で接続すると、EMQXはセッション状態をDSに保存します。

  • メッセージ永続化:

    Durable SessionがQoS > 0のトピックフィルターをサブスクライブすると、そのトピックフィルターはEMQXのルーティングテーブルで「durable」とマークされます。このマークされたトピックにパブリッシュされたメッセージは、レギュラークライアントへの配信に加え、DSにも保存されます。

  • 進捗追跡:

    Durable SessionsはDS内のメッセージをイテレーター(軽量なマーカー)を使って読み取ります。イテレーターは各耐久ストレージストリーム内のセッションの進捗を追跡し、切断やノード再起動後もメッセージの再生を確実に再開可能にします。

  • 効率的なストレージ:

    メッセージは、トピックをサブスクライブするDurable Sessionsの数に関わらず、DSの各レプリカに一度だけ保存されるため、ストレージのオーバーヘッドが最小化されます。

共有サブスクリプションセッション ​

EMQX v6.0以降、DSは共有サブスクリプションセッションの永続化もサポートしています。共有サブスクリプションはDSを利用してサブスクライバーグループ間で一貫したメッセージ分配を維持します。

  • イテレーター管理:

    指定された共有サブスクリプションリーダーがグループのイテレーターセットを管理し、メンバーにイテレーターを割り当てて協調的な消費を保証します。

  • 再生とリバランス:

    共有トピックをサブスクライブするセッションはリーダーと通信し、メッセージ再生用のイテレーターを借ります。更新されたイテレーターはリーダーに報告されます。クライアントが切断されたりグループがリバランスされると、リーダーはイテレーターを取り上げて他のメンバーに再配布し、消費の継続性と負荷分散を確保します。

これらの仕組みにより、サブスクリプショングループ全体でのロードバランシング、メッセージ順序の維持、フォールトトレランスが実現されます。

クラスター全体の耐久ストレージ ​

EMQXクラスター内の各ノードには一意のサイトIDが割り当てられており、Erlangノード名(emqx@...)に依存しない安定した識別子として機能します。サイトIDはノードの初回起動時にランダムに生成され、永続化されます。この安定性により、ノード名の変更や再設定があってもデータの整合性が維持されます。

管理者はemqx_ctl ds info CLIコマンドを使用してクラスター内の各サイトの耐久ストレージ状態を管理・監視できます。

Durable Sessionsのハードウェア要件 ​

セッション耐久性を有効にすると、EMQXはDurable SessionsのメタデータとDurable Sessionsに送信されたMQTTメッセージをディスクに保存します。そのため、十分なストレージ容量を持つサーバーにEMQXをデプロイする必要があります。EMQXのデータディレクトリはローカルファイルシステムを使用しなければなりません。なぜなら組み込み耐久ストレージバックエンドはNFSやSMB/CIFSなどのネットワークファイルシステムをサポートしていないためです。最高のスループットを得るには、ソリッドステートドライブ(SSD)を使用してください。

ディスク容量の目安は以下のガイドラインに基づきます。

  • メッセージストレージ:各レプリカに保存されるメッセージの容量は、受信メッセージのレートとdurable_sessions.message_retention_periodパラメータで指定された保持期間の積に比例します。このパラメータはメッセージの保持期間を決定し、必要な総ストレージ容量に影響します。
  • セッションメタデータストレージ:セッションメタデータの容量は、セッション数とそれらがサブスクライブするストリーム数の積に比例します。
  • ストリーム数の計算:ストリーム数はシャード数に比例し、トピック数にも(非線形に)依存します。EMQXは構造が類似したトピックを自動的に同じストリームにまとめるため、トピック数の増加に対してストリーム数の増加を抑え、セッションごとのメタデータ量を最小限にします。

次のステップ ​

Durable Sessions機能の設定と管理方法、EMQXクラスターでのDurable Sessionsの初期設定や変更方法については、以下のページを参照してください。

詳細情報 ​

MQTT Durable Sessionsの設計原理をより深く理解するには、Design for Durable Storageを参照してください。