MQTTについてのまとめ¶
注釈
MQTT As a Service: sangoをリリースしました
2014年8月に、GitHubアカウントで簡単に登録できてMQTTを使い始められる sango を 時雨堂 がリリースしました。
無料プランもありますので、MQTTを一度使ってみたいという方はsangoを使うことをお勧めします。
最近voluntasさんが 活動 してお り、にわかにMQTT関連が熱くなってきました。たぶん観測範囲が狭いからだと は思いますが。
とはいえ、M2M (Machine to Machine)やIoT(Internet of Things)というバズワー ドもあり、モノがインターネットにつながる時代になってきて、MQTTの価値が 高くなってきている気もします。また、モバイル時代に適したプロトコルとい う意味でも注目されているのかもしれません。
ということ、MQTTについて一旦ここでまとめてみます。
MQTTとはなにか¶
MQTT(MQ Telemetry Transport) とは、publish/subscribeモデルに基づく軽量 なメッセージプロトコルです。ネットワークが不安定な場所で動作するための 機能や非力なデバイスで動くための軽量化などが特徴です。
MQと名前についていますが、負荷を分散させるためのいわゆる Job Queueでは ありません 。そういう用途にはAMQPなどを使ってください。
MQTTはメッセージの配信に特化しており、特に多数のPublisher/Subscriberを 持たなければいけない用途に使われています。また、軽量な点と同期通信な点 を生かして、リアルタイム通信が必要な用途にも使われています。
具体的には
センサーからのデータ収集 (IBMの北九州市の例)
メッセージサービス ( Facebook Messanger )
車とスマホの情報同期 ( Connected Car from CES 2014)
などが挙げられます。
歴史¶
MQTTは元々は1999年からIBMとEurotech社が策定していました。IBMは IBM MessageSight という製 品を持っています。
その後 2011年に Eclipse FoundationにMQTTのコードが寄贈され 、また、2013年 に OASISという国際標準化団体にて標準化 が行われるようになりました。
仕様はロイヤリティフリーで 公開 されています。現在の仕様は3.1が最新で、近々3.1.1が登場します。
特徴¶
MQTTの特徴を簡単にまとめてみます。
固定長2バイトというオーバーヘッドの少なさと処理の軽さ
1対多、多対多のメッセージ配布、しかもTopic wildcardにより柔軟性が高い
アプリケーションの特性に合わせて三種類のQoSを指定可能
「最高1回」「少なくとも一回」「正確に一回」の三種類
切断が発生し、再接続後に切断中のメッセージを受け取れる「Durable subscribe」
Publish側が切断した場合に事前に決めておいたメッセージを流す「Last Will and Testament」
あとからSubscribeしてきた場合に送れるように、最後のメッセージを保存しておく「Retain」
QoS、WillなどはMQTTの特徴的な機能ですね。
なお、MQTTはTCP/IP上で動作し、payloadは仕様では特に決められていません。 文字列が使わることも多いようですし、MessagePackを使っているという話も聞 いたことがあります。
では、これらについて説明していきます。
軽量¶
MQTTは固定長ヘッダーが最小2バイトとオーバーヘッドが少なく、またプロコト ルも単純です。そのため、HTTPに比べるとネットワーク帯域および処理速度に 優れています。また、処理が少ないということで、消費電力も少なくなってお り、モバイル機器にも向いています。
IBMの資料 によると、HTTPに比べて
トラフィックが10分の1から100分の1に、すなわち、10〜100倍のスループット
電池の消費量が10分の1以下に
とのことです。
また、HTTPのようにコネクションレスではなく、一定間隔でheart beatを送り 合う、コネクション指向のプロトコルで、双方向通信を行います。そのため、 即時性が高い通信が可能です。
性能ですが、 別のIBMの資料 では
Linux, 4 x 4-core 2.93GHz Intel Xeon with 32GB of RAM and 10Gbit LAN
で
100,000 クライアント
13,000メッセージ/sec
を
25%のCPU
でさばいたそうです。これは一番軽量な場合(QoS0)ですが、一番重い場合(QoS2)でも、 6000 メッセージ/secを30%のCPU loadでさばいたそうです。
Topic¶
メッセージはそれぞれ「Topic」を持っています。Topicは
/r_rudi/second_house/room10/light/watt
というように / 区切りの階層構造になっています。
Subscriber側では、購読するTopicを指定します。この時完全に一致ではなく、 Wildcardを指定できます。
例えば以下のように指定できます。
- /r_rudi/second_house/room10/light/watt
完全一致指定
- /r_rudi/second_house/#
/r_rudi/second_house/ 以下すべてのtopic
- /r_rudi/second_house/+/light/watt
部分一致 (この場合、すべての部屋のlightのwattを得る)
もちろん一つのsubscriberが複数のtopicをsubscribeできます。
QoS¶
MQTTではメッセージ配信に関してQoSが設定できます。
QoS 0: At most once -- 最高1回。届くかは保証しない。
QoS 1: At least once -- 少なくとも一回。重複する可能性がある。
QoS 2: Exactly once -- 正確に一回
これは送信するメッセージごとに変更できますので、通常はQoS 0で届いても届 かなくてもいいけれども、コントロールメッセージは必ず届くように QoS 1か 2にする、などができます。
QoS 1と2については、ACKや再送の場合などもプロトコル仕様の中で定義されて います。
Durable subscribe¶
MQTTはネットワークが不安定な状況を想定しています。そのため、QoS 1とQoS 2の場合、送られたメッセージを一定期間サーバー(Broker)が保持しておきます。
Subscriberが明示的なDISCONNECTやUNSUBSCRIBEをせずに突然切断した場合、再 接続してきた時にその間のメッセージを再送する機能があります。
これにより、不安定なネットワークやサーバーでも動作できるわけです。
Will¶
クライアントは最初にサーバーにCONNECTした時にWillという情報を追加できま す。サーバーはそのクライアントとの通信ができなくなった場合に、このWill で指定されたTopicとPayloadを送信します。
これにより、Subscriber側でPublish側が死んだということを判断できるわけで す。
なお、死活判定は、一定間隔ごとに送られるpingに答えるかどうかで判断され ます。この間隔も接続のたびに決められますので、このデバイスは電池が心配 だから間隔を長くしよう、などのようなことができます。
Retain¶
Retain機能とは、最後にPublishされたメッセージをMQTTサーバーが保持してお き、新しいSubscriberにそのメッセージを渡す機能です。
MQTTはPublish/Subscribe型モデルです。従って、Publishされた時に Subscribeしていたクライアントにしかメッセージは送信されません。そのため、 例えば1時間ごとに更新される情報を得ようとSubscribeしても、最長1時間はな にも情報が得られないことになります。
しかし、この場合でもRetain機能を使うと最新の情報を得られます。
セキュリティ¶
MQTTは、最初にサーバー(Broker)に接続するときにユーザー名とパスワードを指定するようにできます。 ただし、パスワード自体はクリアテキストで送られてくるのでSSLを通してセキュリティを構 築することになっています。
また、Subscriberの認証もありませんので、このTopicはこのSubscriberだけに 配信しよう、などということも仕様にはありません。ただ、後述のMosquittoは ユーザー名ごとにReadとWriteのアクセス管理をできる機能が実装されています。
さきほどユーザー名とパスワードを指定すると書きましたが、この扱いについ ては実装依存です。通常の認証に加えて、LDAPやOAuthを使って認証をする、と いう実装も可能です。
実装¶
プロトコルが簡単ですので、実装は多くあります。ただ、QoS 0だけだったりと、 きちんと実装されているものは多くありません。
その中で、よく参照されているものを列挙します。
MosquittoはCで書かれた古くからある実装で、ほぼすべての機能を実装してお り、参照実装として扱われることが多いです。
RabbitMQはerlang製の定評あるMQサーバーです。AMQPなどにも対応しています が、MQTTにも対応しています。
Pahoは前述の通りIBMから寄贈された実装で、Java版やPython、JSなど、多彩な 言語に対応しています。
ActiveMQ ApolloはMQTTTの他STOMPやAMQPなどもできます。
また、クローズドソースですが、HiveMQというものもあります。
注釈
時雨堂 さんがMQTT Brokerを作っています。 erlangという言語で実装されており、かなりの速度と耐故障性があるそうで す。
残念ながらクローズドソースですが、そのspecや開発ログなどは こちら から参照できます。
WebSocket¶
WebSocket はHTTP上で双方向通信を行うプロ トコルで、最近のブラウザであればだいたい動作します。
このプロトコルはMQTTの双方向通信と同じ機能を提供するため、ブラウザ上で WebSocketを使ってMQTTサーバーにつなげるライブラリもあります。
まとめ¶
最近微妙に少しだけほんのりと熱くなってきている気がしているけどそうでも ないかもしれないMQTTについてまとめてみました。
軽いプロトコル、コネクション指向、切断検知や再送機能など、いろいろ使え そうなプロトコルです。案外多くの使い方にフィットするかもしれません。
「HTTPですべてを行う」のもいいですが、他のプロトコルも使ってみるのも一 つの考え方かもしれません。
ちなみに、ぼくが書いたMQTT関連のソフトウェアは以下の3つです。どれもコ ンセプトレベルですけど、なにかの参考になれば。
mqtt-kibana: https://bitbucket.org/r_rudi/mqtt-kibana
storm-mqtt: https://github.com/shirou/storm-mqtt
Comments
comments powered by Disqus