ニフクラ ブログ

ニフクラやクラウドの技術について、エンジニアが語るブログです。

ニフティクラウド MQTT のご紹介(前編)

こんにちは。ニフティクラウド MQTT 開発に携わっている もりふじ です。

ニフティクラウドでは IaaS だけでなく RDB や Message Queue、ESS といった、アプリケーション開発に役立つミドルウエアを、簡単に利用できる機能を提供しています。これに加え、5月11日にニフティクラウド MQTT をリリースしました。

これから前編/後編に渡り、今回リリースしたニフティクラウド MQTT について執筆したいと思います。 今回は MQTT についての簡単な紹介と、MQTT 利用に適したケース/必ずしも MQTT を利用しなくてもよいケースについてお話します。次回は、ニフティクラウド MQTT 開発において選定した OSS のベンチマーク取得結果や、そのプラグインへのコントリビュートについてお話ししたいと思います。

1. MQTT とは

MQTT.org には、以下のようにあります。

MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. MQTT は machine-to-machine (M2M) / "Internet of Things" 接続性の高いプロトコルです。 非常に軽量な publish/subscribe 型のメッセージ転送として設計されました。 コードのフットプリントが小さいこと、かつ/またはネットワーク転送が非常に高い場合のリモートコネクションの時に有効です。

というように、下記のような特徴を備えたプロトコルです。

  1. 小さな通信ヘッダ
  2. 1対多、多対多の Pub/Sub 型

1.1. 小さな通信ヘッダ

小さな通信ヘッダについて、少しだけ解説します。

curl コマンドで www.google.com に向けて GET リクエストを投げたときのリクエストヘッダは、次のようになります。

GET / HTTP/1.1
User-Agent: curl/7.37.1
Host: www.google.com
Accept: */*

サイズとしてはこれで 71 バイトです。 User-Agent および Accept は省略可能。また、 Host が自明な場合も省略できますから、

GET / HTTP/1.1

ここまでは小さくできます。それでも 14 バイトです。

これに対して、 MQTT では MQTT V3.1 Protocol Specification にある通り、通信に要するヘッダのサイズは最小 2 バイトで、14 バイトから 12 バイト分も省略できることになります。ヘッダが小さいことで生まれるメリットについては後述します。

1.2. 1対多、多対多の Pub/Sub 型

MQTT は Pub/Sub 型のモデルとなっています。 1 対 1 での通信ではない、中心に MQTT ブローカーをおいたモデルですから、 Publisher と Subscriber が P2P で接続し、組み合わせの数だけ通信コストを低くすることが出来ます。

2. MQTT に適したケース / MQTT でなくともよいケース

2.1. 適したケース/適していないケース

とても小さなヘッダであるということは、通信帯域が制限されている場合、または通信が高コストの場合に意味を持ちます。また、データ転送を行わないで済む、ということはデバイスはその分だけ電力消費量が少なくて済み、ひいてはバッテリーが長持ちするということになります。

先の特徴でも上げたとおり、 HTTP のヘッダを最も小さくした時の差である 12 バイトというのは大きいようで、実は大したことがありません。 あくまで「通信したいデータに対するヘッダの比率が大きい時」に 12 バイトは価値となってきます。

メッセージにおける、全体の通信量におけるヘッダの比率は次のような式で計算できます。

r = body / (body + header)

メッセージサイズ (byte) HTTP MQTT
2 0.125 0.500
22 0.611 0.917
100 0.877 0.980
1000 0.986 0.998

メッセージ全体のサイズが大きくなればなるほど、12 バイトの意義が小さくなっていくのが見て取れると思います。1000 バイトのメッセージを送信するとしたら 12 バイトは誤差と言えると思います。

ただし、ビッグデータのコンテキストと組み合わせて語られる文脈が多いように、通信コストが膨大であれば 12 バイトの価値が大きくなってきます。 Facebook のメッセージが MQTT を利用している理由として、 トータルでのネットワーク利用量、つまりコストがバカにならないと考えた結果だと考えられます。 その他にも、センサーの数が数万~数千万と膨大な数になってきた場合にも大きな価値となります。

同様の理由で Connection をあまり使い回せない状況かつセキュアな通信が求められる場合は、 1 回の Publish に対して毎回認証を含めた接続を行うとコストが大きいため、やりとり全体として 12 バイトの差が小さくなってしまい MQTT の価値が小さくなってきます。

いくつかの事例や、ヒアリングを行っていると「それ HTTP/S でよくない? MQTT である必要ないんじゃ?」ということを耳にします。

2.2. MQTT 適していない事例

たとえば、

  • 「ネットワークアダプタを介して情報を集約し、それをクラウドに貯めたい」
    • データを貯めることが目的であれば、1 対多のメッセージ配送は不要な上、通信帯域もそれほど気を使わなくてもいいはずです。
  • 「電源を取得できる機器であり、それほど頻繁に Pub/Sub しない、またはネットワーク帯域が十分に確保できる」
    • 帯域の心配がなくて、電源が取得できる状況でしたら、扱いやすいその他のプロトコルを選定することも考えましょう。
  • 「Publish ごとにセキュアな接続を行わなければならないような不安定な電波状況での利用」
    • 認証のやりとりをするのであれば、もはやヘッダの 12 バイトとか誤差です、誤差。

など、メリットである 1対多や小さいヘッダが活かせないのであれば別のソリューションを比較することを検討する方が良いかと思います。

2.3. まとめ

サービス全体として、メッセージサイズとヘッダのサイズの比を鑑みた上で取り回しのし易い HTTP/S を利用するのか、 MQTT を利用するのかを考えていくことが必要だと思います。

最後に

今回は MQTT について、そして必ずしも MQTT でなくとも良いケースをご紹介しました。次回は MQTT の実装毎のベンチと、実際に私たちが選定した mosquitto とそのプラグインに送ったコントリビュートについて紹介します。