IoTに特化して設計されたプロトコルであるMQTTは、PCだけでなく、狭帯域ネットワークや低消費電力のデバイスでも利用できます。MQTTでは、メッセージ配信の信頼性をさまざまなネットワーク環境下で保証するQoS
が定められています。
MQTTのQoS
MQTTは3つのQoSレベルを設計しています。
- At most once (0)
- At least once (1)
- Exactly once (2)
QoS 0は"fire and forget"のメッセージ送信モードです。送信者(PublisherかBroker)はメッセージを送信した後、それが相手に送信されたかどうかは確認せず、再送する仕組みも用意しません。
QoS 1には単純な再送メカニズムが含まれています。送信者はメッセージを送信した後、受信者のACKを待ちます。ACKを受信しなかった場合は、メッセージを再送します。このモードでは、メッセージが少なくとも1回は届くことを保証できますが、メッセージが重複して届く場合があります。
QoS 2では、メッセージが一度だけ到着することを保証するために、再送する仕組みと重複を検知する仕組みが用意されています。
動作原理
QoS 0 - Publish once at most
QoS 0の場合、メッセージのPublishはネットワークの能力に左右されます。Publisherはメッセージを一度だけ発行します。受信者はメッセージを受け取っても返信せず、Publisherはメッセージの保存や再送を行いません。QoS 0では、メッセージの伝送効率が最も高くなりますが、メッセージが配信されない場合もあります。
Qos 1 - Publish once at least
QoSが1の場合、メッセージは少なくとも1回はPublishされることが保証されます。MQTTでは、ACKを受け取るシンプルな仕組みによってQoS 1を保証しています。Publisherはメッセージを発行して、受信者のPUBACKパケットが返ってくるを待ちます。指定された時間内にPUBACKを受信しなかった場合、PublisherはメッセージのDUP
フラグを0から1に変更し、メッセージを再送します。受信者は、QoS 1のメッセージを受信したときには、PUBACKに応答する必要があります。受信者は同じメッセージを複数回受けとる場合があります。DUP
フラグが0でも1でも、受信者は受信したメッセージを新しいメッセージとして扱い、応答としてPUBACKパケットを送信します。
QoS 2 - Publish only once
QoS 2の場合、PublisherとSubscriberは、2つのセッションを通じてメッセージが1回だけPublishされるようにします。これはMQTTにおいて最も高いQoSで、メッセージが失われたり重複したりすることを許容しません。QoS 2を使用する場合、通信は他のQoSと比べて遅くなります。
QoS 2のメッセージをPublishした後、送信者はPublishしたメッセージを保存し、受信者からPUBRECが返ってくるのを待ちます。送信者はPUBRECを受信することで、受信者がメッセージを正常に受信したことを知り、そのメッセージを破棄します。送信者はPUBRECを保存してPUBREL(PUBLISHのリリース)を受信者に返し、受信者がPUBCOMPメッセージで応答するのを待ちます。送信者はPUBCOMPメッセージを受信すると、保存していた状態を全て破棄します。
受信者は、QoS 2のメッセージを受信すると、そのメッセージを処理し、応答としてPUBRECを返します。また、PUBRELメッセージを受け取った受信者は、保存されていたすべての状態を破棄し、PUBCOMPで応答します。
送信中にパケットロスが発生した場合は、送信者は前のメッセージを再送します。これは、送信者がPublisherであるかBrokerであるかに関わらず同様です。また、受信者も各コマンドに応答する必要があります。
PublishとSubscribeにおけるQoS
MQTTにおけるQoSは、エンドツーエンドではなく、クライアントとサーバーの間に適応されます。そして、あるメッセージにおいて、Subscriber-Broker間のQoSが、Publisher-Broker間のQoSよりも高い場合、Subscriber-Broker間のQoSはPublisher-Broker間のQoSまで下がります。つまり、以下の表のようになります。
publishのQoS | SubscribeのQoS | メッセージのQoS |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
0 | 2 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
1 | 2 | 1 |
2 | 0 | 0 |
2 | 1 | 1 |
2 | 2 | 2 |
QoSの選び方
QoSが高いほど、処理が複雑になり、リソースの消費は多くなります。ネットワークやビジネス要件に応じて、それぞれのアプリケーションに適切なQoSを選択しましょう。
QoS 0を選ぶユースケース
- たまにメッセージが失われることがあることを受け入れられる場合
- 同じサブネット内の内部サービスとしてMQTTを使う場合
- クライアントとサーバーのネットワーク間が非常に安定している場合
QoS 1を選ぶユースケース
- パフォーマンスの最適化を望む場合 (QoS 2では重い場合)
- メッセージを失いたくはないが、メッセージの重複については処理が可能な場合
QoS 2を選ぶユースケース
- メッセージの損失も避けなければならないが、重複したメッセージは受け取りたくない場合
- 銀行、消防、航空など、高いデータの完全性と適時性が要求される業種の場合