MQTTバージョン5の概要 第5回 考察 MQTTはIoTにおいてHTTP/RESTを完全に駆逐する

連載最終回は、MQTTバージョン5の標準化ドラフトの意味付けを考察します。

<font color="Red">2017/3/28更新 1(1)、2(1)の記載を見直しました。</font>

連載目次

[第1回 標準化の狙い] (http://qiita.com/items/bd21ce2995f313521c56) (2017/2/25)
[第2回 旧バージョンからの主な変更点 1〜3.2] (http://qiita.com/items/71f1e4f4e40d0033822d) (2017/3/9)
[第3回 旧バージョンからの主な変更点 3.3〜3.15]
(http://qiita.com/items/563f2c67639318c5c3d6) (2017/3/12)
[第4回 旧バージョンからの主な変更点 4〜] (http://qiita.com/items/8cf99f01a4dc1530a137) (2017/3/18)
[第5回 考察 MQTTはIoTにおいてHTTP/RESTを完全に駆逐する] (http://qiita.com/items/00cb2050ae68b45bb931) (2017/3/18)

これまで、MQTTはIoT向きと言われていましたが、実際に使ってみると、そこまで有用ではなく、HTTP/RESTの方がマシと思われることが多くありました。しかし、今回のバージョン5により、MQTTが持っていた欠点の多くが解消され、IoTにおいて、HTTP/RESTを完全に駆逐する可能性が出たと考えます。

さらに、連載の最後として、今後のMQTTブローカーサービスがどのようになっていくかについて、大胆予想を記述してみました。

# 1. MQTT従来バージョンの不明確な長所と明確な短所

MQTTの良く宣伝される長所として、以下があります。

+ (1)通信におけるオーバーヘッドが少ない。
+ (2)電力消費が少ない。
+ (3)センターPUSH（センターから端末に対して即時にメッセージを送信することができる）が可能。

しかし、現実に利用してみると、上記の長所はあまり発揮できません。

上記長所の多くはMQTTがコネクション型であることに依拠していますが、現実の端末は、セルラーやWi-Fiなどの無線環境下にあったり、ファイアウォール配下にあったりするため、コネクションを常時接続することが難しいのです。

コネクション常時接続できない場合、上記の長所は以下のようになります。

+ (1)オーバーヘッド少とは言えない。
  + １メッセージを送信するたびにネットワークコネクションを切断していると、PUBLISHのほかに、CONNECT、DISCONNECTが必要になるため、オーバーヘッドはHTTPとあまり変わらない。セッションという概念で再接続時のオーバーヘッドを減らすことができるが、無期限であり実際には使いにくかった。
  + 認証セキュリティを高める手段がTLSになり、余計なオーバーヘッドがついてしまう。
+ (2)電力消費少とは言えない。
  + 上記のため、電力消費はHTTPと変わらない。
  + 逆に、モバイル常時接続環境でコネクションを維持する場合は、回線を維持するための電力が大きいため、HTTPよりも電力を使ってしまう場合も多い。
  + 認証セキュリティを高める手段としてTLSを使と、計算パワーが必要で、消費電力に悪影響がある。
+ (3)センターPUSHはできないことも多い。
  + コネクション維持できていないと、センターPUSHは機能しない。

一方、HTTP/RESTと比較して、MQTTには以下のような短所があります。

+ (4)表現力が乏しい。
  + HTTPヘッダやレスポンスコードなど、HTTPでは様々な標準および拡張の取り決めがあるが、MQTTにはそのようなものは無いため、実運用システムが作りにくい。
+ (5)要求応答ができない。
  + 上記の一部であるが、一方的に送りつけるPUBLISHが唯一のメッセージ送信手段であるため、クライアントからのリクエストに応じてサーバーがレスポンスを返す、という基本的なパターンが実現しにくい。
+ (6)エンドツーエンドの到達確認の仕組みがない。
  + 必ずサーバー（ブローカー）を介して通信をする必要があり、QoSはクライアントとサーバーの間のホップバイホップで機能するため、エンドツーエンドでの到達確認の仕組みがない。
+ (7)メッセージを紛失しやすい。
  + 上記と類似だが、MQTTは、温度センサー情報などの連続的な値を定期的に通知するようなユースケースが主であるため、途中情報の抜けに寛容である。サブスクライバーが接続していない場合に、パブリッシャーがメッセージを連続的にPUBLISHすると、RETAINオプションをつけても、最後のメッセージしか到達できない。
  + QoS1/2でセッション維持をすると、サブスクライバー未接続時のメッセージを複数取得することが可能になるが、セッション維持時間が無期限となっており、実用上は使いにくかった。
+ (8)セキュリティ面で不足がある。
  + 軽量クライアントとの通信においてTLS暗号化は使えないか、使いたくない場面が多い。しかし、CONNECTでの認証のしくみが単純であるため、TLS暗号化が無いと、パスワードがプレーンテキストでネットワークを流れてしまう。
+ (9)サーバーの性能拡張や冗長構成をとることがやりにくい。
  + コネクション型かつステートフルなプロトコルであるため、単純な負荷分散構成をとることができない。

そのため、実運用システムにおいて、本当に便利だから、という理由でMQTTを使うことは、あまり無いのが実情でした。（流行りだから、利用しているPaaSがそれしかサポートしていないから、という理由は多くあります（笑）。もちろん、「不明確な長所」を信じ込んでしまっている場合もあるでしょう。）

# 2. MQTTバージョン5による改善

MQTTバージョン5において、これまで述べた不明確な長所や欠点が、解消されています。

+ (1)改善された。
  + セッションに有効期限を新たに設け、使いやすくなった。
  + 拡張認証機構により、TLSの必要性が減った。
  + Topic Aliasというさらに効率化が目指せるプロパティができた。なお、これはネットワークコネクションを超えては機能しないため、効果は限定的である。しかし、同じネットワークコネクションを維持したまま複数のメッセージを送信するという、もともとMQTTが得意としているユースケースであれば、長所をより一層強化するものになっている。
+ (2)改善された。
  + 上記の波及効果として、ネットワークコネクションの常時接続を前提としない中で、電力消費量も削減可能になる。
+ (3)これについては変更なし。
+ (4)改善された。
  + 新規に導入されたUser Propertyは、HTTPヘッダと対応する使い方が可能になる。またエラーコードは大幅に強化された。
+ (5)改善された。
  + 要求応答のシーケンスを利用することで、応答側が持つ１つまたは複数の情報を、クエリーにより検索取得するようなパターンが実現可能になった。
+ (6)改善された。
  + 要求応答のシーケンスを利用することで、エンドツーエンドの応答確認が可能になった。
+ (7)改善された。
  + (6)と同様に、エンドツーエンドの応答確認により、メッセージ紛失の検出や再送がやりやすくなった。
  + フロー制御により、メッセージを紛失しにくいようになった。
  + (5)により、サーバーを経由して応答側が保持する複数のメッセージを一度に受信する、といったパターンも実現可能になった。
  + 従来バージョンでの唯一の方法であるQoS1/2によるセッション維持により対応する場合でも、セッション有効期限が設定できるようになり、現実的に利用できるようになった。
+ (8)改善された。
  + 拡張認証機構により、パスワードやトークンに関するチャレンジレスポンスシーケンスなどもサポート可能となった。
+ (9)一部改善された。
  + 共有サブスクリプションやサーバーリダイレクトにより、コネクション型の制約下ではあるが、性能負荷分散や冗長構成をサポート可能となった。

今回のバージョン5により、MQTTが持っていた欠点の多くが解消され、IoTにおいて、HTTP/RESTを完全に駆逐する可能性が出たと考えます。

実際には、1日に1メッセージだけセンサー情報を送信するようなユースケースでは、MQTTバージョン5であっても、わざわざMQTTを使う必要性は少ないです。しかし、基本的にはネットワークコネクション維持しているがモバイル環境下のため頻繁に切断してしまうようなユースケース、特に自動車などでは、MQTTバージョン5による長所の明確化と短所の改善により、MQTTの利用がはっきりと拡大するでしょう。

# 3. 今後のMQTTブローカーサービスに与える影響

現在、様々なクラウドサービスにおいて、MQTTブローカーサービスまたはそれを含むIoT PaaSが提供されています。MQTTバージョン5が普及すると、それらのサービスのあり方に、次のような影響を与えると思います。

+ ブローカーと後段アプリ〜DBのサービス統合。
  + HTTP/RESTに近づくということは、後段のアプリサーバ〜DBサーバーまで存在して初めて意味を持つシステムになるということである。User Propertyやエラーコードなど、MQTT標準としては枠組みしか規定されておらず、どのようにそれらを使うかは、実装に依存してくる。すなわちMQTTブローカーと、アプリ〜DBの設計が密接に連携してしまう。特に、要求応答は、まさしく後段のアプリサーバ〜DBサーバーへのクエリー発行とその応答に他ならない。こういったことを考えると、MQTTブローカーだけ単独で切り出したPaaSは、使いにくなってしまう。
  + すなわち、ブローカー、アプリ、DBが一体となり、ある程度の型を決めたもの、場合によっては特定業務に特化したものが、全体として１つのPaaSになっていく。
  + 上記と並列で逆のシナリオとして、MQTTブローカーは開発ライブラリやコンポーネントとして、個別アプリケーション開発に使われる、という形も進んでいく。現状は、ブローカーだけは外部PaaSとして存在して、開発環境にMQTTクライアントのライブラリが提供される、という形か一般的である。これが変化して、外部PaaSは無くなり、ブローカーもオープンソースで自前で構築運用する前提で、自分のアプリにあわせた細かいカスタマイズをしていく、というシナリオである。進んだ開発環境では、ブローカーの構築運用がある程度簡略化される、といったこともあるだろう。
  + いずれにしても、ブローカー単体PaaSは、その役割が無くなり、廃れていくものと思われる。
  + 技術的可能性としては、「多様なカスタマイズ項目をAPIとして提供するMQTTブローカーサービス」という姿もありうる。しかし、HTTP/RESTの世界において、WebサーバーだけのPaaSなんてものは存在していない。もはや、MQTTにおいても、ブローカーだけのPaaSは、マイクロサービスとして有用な存在にはならなくなると予想する。
+ MQTT非暗号化のサポート。
  + 現状のIoT PaaSは、暗号化しかサポートしていないものが存在している。特にAWS IoTは、暗号化はもちろんのことX.509クライアント証明書が必須という、低リソースクライアントを前提としたIoTのユースケースとしては異例の仕様になっている。
  + 拡張認証のサポートにより、IoT PaaSのMQTT非暗号化サポートが進み、使いやすいものになると予想する。
+ 互換性の後退。
  + 新規に追加された様々なプロパティや、要求応答などエンドツーエンド機能のサポートにより、単純にMQTTをサポートしているといっても、お互いの接続性は全く保証されない、というケースがほとんどになる（現在も既にそういう状況であるがさらに後退する）と予想する。
  + これはHTTP/RESTでは当たり前の世界であり、Facebookクライアントは、Twitterには接続できないのは当然である（Twitter連携する機能はあるよ、という突っ込みはしないように）。
  + 標準プロトコルサポートが、アプリケーションの接続性を保証するわけではなく、オープンソースライブラリの利用により通信レイヤーの個別開発量を大きく削減でき、全体の開発生産性や品質を向上するだけである、という当然の事実が再認識される。

以上で連載は終了です。WDが更新されたら、追記したいと思います。