# 機能と利点

EMQXはMQTT over QUICのために独自のメッセージ伝送機構と管理方法を設計し、現代の複雑なネットワーク上でMQTTメッセージをより効率的かつ安全に伝送できるようにすることで、特定のシナリオにおけるMQTTのパフォーマンスを向上させています。

本ページではMQTT over QUICの利点と、各QUIC動作モードのメリットおよびユースケースについて紹介します。

## MQTT over QUICの利点

QUICはTCPとUDPの機能を統合しつつ、現代のネットワークにおけるレイテンシ問題に対応するための追加改善を導入しています。QUICの利点は以下の通りです。

- **レイテンシの低減**  
  QUICは接続確立時間の短縮を明確に目的として設計されています。従来のTCP上のMQTTでは、TCPハンドシェイクの後に別途TLSハンドシェイクが必要であり、特にモバイルネットワークや不安定な接続環境で遅延が発生します。QUICはトランスポートとTLSのハンドシェイクを統合しており、MQTT接続の確立がより迅速に行えます。

- **ヘッドオブラインブロッキングのないマルチプレクシング**  
  QUICは単一接続上で複数のストリームをマルチプレクシングできます。TCPではあるストリームのパケット損失が他のストリームの処理をブロックするヘッドオブラインブロッキングが発生しますが、QUICでは各ストリームが独立しているため、複数トピックやメッセージストリームを同時に扱うMQTTアプリケーションに有利です。

- **不安定なネットワークでの優れた性能**  
  QUICはTCPに比べてパケット損失やネットワーク変動（例：Wi-Fiとセルラーの切り替え）に強く設計されています。頻繁にネットワークが途切れる環境やモバイルデバイスで動作するMQTTアプリケーションにおいて、よりレジリエントな接続を提供します。

- **組み込みのセキュリティ**  
  QUICはTLS相当のセキュリティ機能を標準で備えているため、MQTT over QUICは追加設定なしに常に暗号化・認証された通信を実現します。

- **接続マイグレーション**  
  クライアントのIPアドレスやポートが変わっても接続を再確立することなく継続可能です。移動中のMQTTデバイスにとって、ネットワークが変わっても接続が持続することは大きなメリットです。

- **改善された輻輳制御**  
  TCPの輻輳制御は長年の実績がありますが、QUICは新しく柔軟なアルゴリズムを導入可能で、輻輳したネットワーク環境下でMQTTメッセージのスループットや応答性を向上させる可能性があります。

## QUICの動作モード

現在のEMQXの実装では、トランスポート層をQUICストリームに置き換え、クライアントが接続を開始して双方向ストリームを作成します。EMQXとクライアントはこのストリーム上でやり取りを行います。複雑なネットワーク環境を考慮し、クライアントが何らかの理由でQUICハンドシェイクに失敗した場合は、自動的に従来のTCPにフォールバックしてサーバーとの通信障害を回避します。EMQXとクライアント間のやり取りには、[シングルストリームモード](#single-stream-mode)と[マルチストリームモード](#multi-streams-mode)の2つのモードがあります。以下では各モードの特徴と利点を紹介します。

<img src="./assets/mqtt-over-quic.png" alt="QUIC上のMQTT" style="zoom:25%;" />

### シングルストリームモード

シングルストリームモードは、MQTTパケットを単一の双方向QUICストリームにカプセル化する基本モードです。高速なハンドシェイク、順序付けられたデータ配信、接続再開、0-RTT、クライアントアドレスのマイグレーション、パケット損失検出と回復の強化を提供します。このモードにより、クライアントとEMQX間の通信が高速かつ効率的になり、順序を維持しつつ接続の迅速な回復やクライアントのローカルアドレスの移行が大きな障害なく可能となります。

<img src="./assets/quic-single-stream-mode.png" alt="image-20231020154933157" style="zoom:67%;" />

#### 特徴と利点

シングルストリームモードの特徴と利点は以下の通りです。

- 高速なハンドシェイク  
  クライアントとEMQX間のQUIC接続は1往復以内で確立可能です。

- 順序付けられたデータ配信  
  TCP同様、MQTTパケットの配信はストリーム内で送信されたメッセージの順序に従います。UDPのデータグラムが順不同で受信されても順序は保たれます。

- 接続再開、0-RTT  
  0-RTT方式により、クライアントは接続を再開し、最初のQUICパケットまたは直後にアプリケーションデータをサーバーに送信可能です。EMQXの応答を待って往復を完了する必要がありません。これはネットワーク障害で切断された接続を迅速に復旧し、アプリケーション業務を速やかに再開するのに特に有用です。

- クライアントアドレスのマイグレーション  
  QUIC接続を切断・再確立することなく、クライアントはNATリバインドなどによりローカルアドレスを新しいアドレスに能動的または受動的に移行できます。これによりMQTT層以上で大きな障害なく接続を維持可能です。

- パケット損失検出と回復  
  QUICは他のプロトコルに比べパケット損失の検出と回復が迅速であり、用途に応じて動作を調整できます。

### マルチストリームモード

マルチストリームモードはQUICのストリーム多重化機能を活用し、MQTTパケットを複数のストリームで伝送します。これにより単一のMQTT接続で複数トピックのデータを扱え、接続制御とMQTTデータ交換の分離、ヘッドオブラインブロッキングの回避、アップリンク・ダウンリンクデータの分割、異なるデータの優先順位付け、並列処理の向上、堅牢性の強化、データストリームのトラフィック制御、サブスクリプションレイテンシの低減など多くの改善が可能です。

<img src="./assets/quic-multi-stream-mode.png" alt="image-20231020155006197" style="zoom:67%;" />

クライアントからEMQXに最初に確立されるストリームはコントロールストリームと呼ばれ、MQTT接続の維持や更新を担当します。その後、クライアントはパブリッシュやサブスクライブ用に1つまたは複数のデータストリームを開始できます。

クライアントはストリームの割り当て方法を自由に選択可能です。例：

- トピックごとに1つのストリームを使う  
- QoS 1用とQoS 0用でストリームを分ける  
- パブリッシュ用とサブスクライブ用でストリームを分ける（コントロールストリーム上でのパブリッシュ／サブスクライブも可能）

ブローカーであるEMQXは以下のストリームパケットバインディングを行います。

- QoS 1のPUBLISHを受信したストリーム上でPUBACKパケットを送信し、QoS 2パケットも同様に処理  
- トピックのサブスクリプションを受けたストリーム上でPUBLISHパケットを送信し、同じストリームからQoS 1のPUBACKを期待

::: tip

データの順序はストリームごとに維持されます。したがって、2つのトピックのデータが相関しており順序が重要な場合は、同じストリームに割り当てるべきです。
:::

#### 特徴と利点

マルチストリームモードの特徴と利点は以下の通りです。

- 接続制御とMQTTデータ交換の分離  
  CONNECT、CONNACK、PINGなどの接続制御パケットはコントロールストリームで処理し、パブリッシュやサブスクライブなどのデータ交換はデータストリームで行います。データストリームが遅くても、PINGREQ/PINGRESPの処理により接続は維持されます。

- トピック間のヘッドオブラインブロッキング回避  
  MQTT over QUICは異なるトピックごとに複数のデータストリームを許可し、異なるトピックのメッセージを独立して配信できます。

- アップリンク（パブリッシュ）とダウンリンク（サブスクライブ）データの分割  
  例として、クライアントは1つのストリームでQoS 1メッセージをパブリッシュし、そのストリーム上でPUBACKを処理し、別のストリームでブローカーからのQoS 0メッセージを受信できます。

- 異なるデータの優先順位付け  
  マルチストリームにより異なるMQTTトピックのデータを優先順位付けして配信可能で、接続の全体的なパフォーマンスと応答性を向上させます。

- クライアントとEMQX側の処理並列性の向上  
  データストリームの利用により、EMQXとクライアントは複数ストリームを並列処理でき、システム全体の効率とリソース利用率が向上し、レイテンシ低減とアプリケーション層の応答速度向上を実現します。

- エラー処理のオーバーヘッド削減  
  1つのデータストリームがアプリケーションエラーで中断されても、接続全体が閉じることはなく、アプリケーションは自由にストリームを再作成してデータを回復できます。これにより、より信頼性とレジリエンスの高いMQTT通信が可能です。

- データストリームごとのフロー制御  
  フロー制御をストリーム単位で適用でき、トピックやQoSレベルごとに異なる制御ポリシーを設定可能です。

- サブスクリプションレイテンシの低減  
  クライアントはMQTTのCONNACKを待たずにサブスクライブやパブリッシュパケットを送信可能です。ただし、EMQXはクライアントの接続確立と許可後に処理を開始します。
