MQTTの通信は本当に軽いのか?

2017.06.30

YDCラボ研究員 草野

新しい技術の実用化を目指す社内プロジェクト「YDCラボ」では、分科会などの場を通して、各メンバーが日頃より積極的に研究テーマに取り組んでいます。

今回は、「IoT」を支える通信プロトコル「MQTT」についてご紹介します。

題して、「MQTTの通信は本当に軽いのか?」

■さっそく比較検証

YDCラボでは、会議室の利用状況をデータ収集する会議室システムを実験的に運用しています。

今回は、このシステムを使って、HTTP、MQTTの通信を確認してみます。

※今回は本題の解説のしやすさを重視し、SYN-ACKやTCPレベルのパケット分割の話は割愛していますのでご了承ください。

<全体構成>
クライアントからはブラウザでサーバーへアクセスし、サーバーには各種センサーからデータが上がってくる仕組みとなっています。

server.png

通信の主文は、会議室システムにおいてbusy/emptyを通知する以下の情報です。

sensor/arduino/conference2/tokyo7f/YDC [{ "sensors":{"conference":"empty"} }]

sensor/arduino/conference2/tokyo7f/YDC
この部分は、会議室を特定するためのTOPIC情報です。

[{ "sensors":{"conference":"empty"} }]
こちらは、どんな状態遷移が起きたかを示すJSON文字列です。

では、その通信の中身を確認してみましょう。
※\r\nはCRLFです。

■HTTPの通信

[Request]
クライアントからサーバーに対して要求を出す部分です。

server2.png

この通信で送信されている情報は以下の通りです。


GET /mqtt.html HTTP/1.1\r\n

Host: 〇〇.〇〇.〇〇.〇\r\n
Connection: keep-alive\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate, sdch\r\n
Accept-Language: ja,en-US;q=0.8,en;q=0.6\r\n
\r\n

今回の検証ではmqtt.htmlを用意し、そこへGoogle Chromeからアクセスしました。通常のGET要求が届いています。
ブラウザからWebサーバーへアクセスすると、このような情報が送信されています。
また、POST要求の場合、末尾の\r\nのあとでPOSTのBODY部が続きます。
今回のこの要求は、428byteありました。

さて、これに対してWebSeverが返したレスポンスを見てみましょう。
[Response]

server3.png


HTTP/1.1 200 OK\r\n

Date: Tue, 28 Feb 2017 00:49:02 GMT\r\n
Server: Apache/2.2.3 (CentOS)\r\n
Last-Modified: Tue, 28 Feb 2017 00:43:02 GMT\r\n
ETag: "3af8604-4d-7a709180"\r\n
Accept-Ranges: bytes\r\n
Content-Length: 77\r\n
Connection: close\r\n
Content-Type: text/html\r\n
\r\n
sensor/arduino/conference4/tokyo6f/YDC[{ "sensors":{"conference":"empty"} }]\n

ご覧のとおり、目的の情報を取得することができました。Content-Length方式で返しています。最後の、
sensorで始まっている行が先述の通信データ本体を示しています。
このレスポンスは326byteありました。つまり、この一度の通信のやり取りで合計754byteのデータのやり取りが発生したことになります。

■MQTTの通信

では、MQTTの通信を見てみましょう。MQTTはコネクション指向のプロトコルです。今回は、ブラウザを使ってWebSocket通信を行います。始めの要求はHTTPで到着し、WebSocketへのUpgrade指令が付与されてきます。

[Request]

server4.png


GET /mqtt HTTP/1.1\r\n

Host: 〇〇.〇〇.〇〇〇.〇〇〇\r\n
Connection: Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade: websocket\r\n
Origin: http://〇〇.〇〇.〇〇.〇〇〇:30080\r\n
Sec-WebSocket-Version: 13\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\n
Accept-Encoding: gzip, deflate, sdch\r\n
Accept-Language: ja,en-US;q=0.8,en;q=0.6\r\n
Sec-WebSocket-Key: vNCUlWIhv1btXT4lMaAVqw==\r\n
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n
Sec-WebSocket-Protocol: mqtt\r\n
\r\n

WebSocketの情報が付与されています。この要求のサイズは536byteでした。

これに対し、サーバーからレスポンスが返ってきます。

[Response]

server5.png


HTTP/1.1 101 Switching Protocols\r\n

Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Accept: pGsaZxRVUQyAAaJ4jr0Ti4nGpQ8=\r\n
Sec-WebSocket-Protocol: mqtt\r\n\r\n

先ほどのWebSocketへのUpgradeを了承する応答が返ってきました。このレスポンスは159byteです。

この後、SYN-ACKのやり取りを繰り返し経て、コネクションが確立されます。今回はこの部分の詳細は割愛し、回数と送受信サイズのみをお知らせします。
通信回数:72回
通信データ量921byte

ソケットの通信を確立するのは大変ですね。
ここまでの準備を経て、ようやくWebSocketによるMQTTの通信が可能になりました。

その後、サーバーから飛んできた情報がこちら。


\82N0L\00&sensor/arduino/conference2/tokyo7f/YDC{ "sensors":{"conference":"empty"} }

MQTTでも目的の情報を取得することができました。

※\82と\00はバイナリコードです。
このデータは80byteということになります。

ということで、ここまでのMQTT通信は合計1696byteとなりました。
HTTP通信が合計754byteでしたので、倍以上のサイズになっています。

■MQTTが「軽い」とは?

では、今回の検証の本題「MQTTは、HTTPと比較して軽い」とはどういうことか?
IoTではセンサーデータのやりとりが頻繁に発生します。
つまり、ここまでで紹介した通信を何度も行うことになります。

HTTPの通信では、毎回754byteの通信が必要です。

さらに、HTTPの場合、トリガーはクライアントにあるため、ポーリングするなどして新情報を確認する必要があります。このポーリング処理は空振りがつきものですが、空振りであったとしても679byteの送受信が発生してしまいます。

server6.png

一方、WebSocketによるMQTTは双方向受信が可能です。一度コネクションを確立してしまえば、いちいち確認せずとも、サーバーから一方的に80byteを送ることで完了できます。

server7.png

試しに、HTTPでは空振りなく情報を取得できたという前提で、通信回数ごとの通信量を比較してみました。

mqtt2.png

当然のことですが、3度目の情報取得で通信量は逆転し、以降はどんどん差が広がります。100回目には、WebSocketによるMQTTの通信量は、HTTPに対してわずか13%という通信料になります。

■MQTTはIoTに欠かせない

センサーデータというものは常時計測され、送信されています。リアルタイムに見せたい情報ほど何度も通信を行う必要があるため、この軽さは大きなアドバンテージとなるわけです。IoTを扱う上で、MQTTの通信が重宝される理由がおわかりいただけますでしょうか。

いやはや、先人の方々はすごいですね。HTTPの初版は1990年の末に登場しましたが、30年近くたった今も現役であり、最先端であるわけです。

個人的には、こういった見えない部分の仕組みを理解しているかいないかで、技術者としてのレベルに差が出ると考えています。特に若い技術者の方々には、ぜひ一度眺めていただけたらな、と思います。

それでは今回はこの辺で。

次回の記事もお楽しみに!