IoTプロトコル

MQTT

軽量なPub/Sub型メッセージング。IoTの定番。

概要

MQTT(Message Queuing Telemetry Transport)は、TCP/IP上で動作する軽量なPub/Sub(発行/購読)型メッセージングプロトコルです。もともと1999年にIBMのAndy Stanford-ClarkとArcom(現Eurotech)のArlen Nipperが、油田パイプラインの監視システム向けに設計しました。現在はOASIS標準となっており、IoTデバイスが少ないリソースでクラウドやサーバーと通信するためのデファクトスタンダードとして広く使われています。

MQTTの最大の特徴は「軽量さ」にあります。ヘッダの最小サイズはわずか2バイトであり、帯域幅が限られたLPWAやセルラーIoT回線、あるいはメモリが少ないMCU上でも動作できます。また、Pub/Subモデルを採用することで、センサーデバイスと処理サーバーを完全に疎結合にでき、スケーラブルなシステムを構築しやすくなっています。

歴史・背景

1999年にIBMとArcomが衛星回線を介した石油パイプライン監視のために開発したのがMQTTの始まりです。当初は独自プロトコルでしたが、2010年にロイヤリティフリーで仕様を公開し、2013年にはOASISによって標準化プロセスが開始されました。

2014年にMQTT 3.1.1がOASIS標準として正式リリースされ、同年ISO/IEC 20922としても承認されました。その後、2019年にはMQTT 5.0がリリースされ、エラーレポートの強化・セッション有効期限・共有サブスクリプション・トピックエイリアスなど多くの機能追加が行われました。

2010年代のIoTブームを経て、AWS IoT CoreAzure IoT Hub・Google Cloud IoT Coreなどの主要クラウドプラットフォームがMQTTを標準サポートしたことで、デファクトスタンダードとして確固たる地位を占めるようになりました。

技術仕様

プロトコル基本仕様

項目仕様
トランスポート層TCP/IP(MQTT over TLS/SSLも標準)
標準ポート1883(非暗号化)、8883(TLS)
最小ヘッダサイズ2バイト
最大メッセージペイロード256MB(MQTT 3.1.1)、理論上は同じ(MQTT 5.0)
QoSレベル0・1・2の3段階
プロトコルバージョン3.1、3.1.1、5.0

QoS(Quality of Service)レベル

MQTTはメッセージ配信の信頼性をQoSで制御します。

  • QoS 0(At most once): 送りっぱなし。確認なし。最も軽量だが、ネットワーク障害時にメッセージが失われる可能性がある。センサーデータの高頻度送信など、多少のロストが許容できる用途に向く。
  • QoS 1(At least once): 少なくとも1回配信。ブローカーからのACKを待つ。重複配信の可能性がある。
  • QoS 2(Exactly once): 正確に1回配信。4ウェイハンドシェイクで重複を防ぐ。最も信頼性が高いが、通信オーバーヘッドも最大。

トピック構造

MQTTのメッセージはトピックと呼ばれる階層的な文字列で分類されます。スラッシュ(/)で階層を区切り、ワイルドカード(+・#)で購読範囲を指定できます。

# トピック例
factory/line1/sensor/temperature
building/floor3/room201/humidity
device/ESP32-001/status

# ワイルドカード購読(+は1階層、#は複数階層)
factory/+/sensor/temperature    # 全ラインの温度
factory/line1/#                 # line1配下の全データ

MQTT 5.0の主要追加機能

  • セッション有効期限(Session Expiry Interval): セッションをサーバー上に保持する期間を秒単位で指定
  • 理由コード(Reason Code): ACKパケットに詳細なエラーコードを付与
  • ユーザープロパティ(User Properties): 任意のキーバリューペアをメッセージに添付
  • 共有サブスクリプション(Shared Subscriptions): 負荷分散のため複数クライアントでトピックを共有
  • トピックエイリアス(Topic Alias): 長いトピック名を短い数値で代替してペイロードを削減

動作原理

MQTTは「ブローカー」と呼ばれる中継サーバーを介した通信を行います。デバイス(パブリッシャー)はブローカーにメッセージを送信し、ブローカーはそのトピックを購読しているクライアント(サブスクライバー)にメッセージを転送します。

[デバイス A] ---PUBLISH---> [ブローカー] ---PUSH---> [クラウドサーバー]
                                  ^
[デバイス B] ---SUBSCRIBE---------|

接続シーケンス

  1. クライアントがブローカーにTCP接続を確立
  2. CONNECTパケットを送信(クライアントID、KeepAlive、認証情報等を含む)
  3. ブローカーがCONNACKで応答(接続受理/拒否)
  4. クライアントがSUBSCRIBEでトピックを登録
  5. ブローカーがSUBACKで確認
  6. パブリッシャーがPUBLISHでメッセージ送信
  7. ブローカーがサブスクライバーへPUBLISHで転送

Retain機能とLast Will

Retain(保持): ブローカーが最後に受信したメッセージをトピックに保持します。新規サブスクライバーは接続直後に最新値を取得でき、センサーの現在値を即座に知ることができます。

Last Will and Testament(LWT): 接続時にLWTメッセージを登録しておくと、デバイスが異常切断した場合にブローカーが自動的にそのメッセージを発行します。デバイスのオフライン通知に活用されます。

用途・ユースケース

センサーデータ収集

温度・湿度・圧力などのセンサー値を定期的にブローカーへパブリッシュする用途が最も基本的な活用例です。QoS 0または1を使い、低消費電力・低帯域での継続的なデータ収集を実現します。

デバイス制御・コマンド送信

クラウドからデバイスへのコマンド(LED点灯・モーター制御・設定変更)もMQTTで実現できます。デバイスが制御用トピックをサブスクライブしておき、サーバーからコマンドをパブリッシュする構成が一般的です。

OTA(無線アップデート)

ファームウェアの更新通知や更新ファイルのダウンロードURLをMQTTで配信し、デバイス側でファームウェアを取得・適用するOTA更新フローに利用されます。

産業IoT(IIoT)

PLCやセンサーからのデータをMQTTでクラウドへ集約し、生産ラインの監視・品質管理・予知保全を行うユースケースが増加しています。

実装・開発のポイント

ブローカーの選定

ブローカー特徴
Eclipse Mosquitto軽量・OSSの定番。組み込みデバイス向けにも使われる
EMQX高スループット・クラスタリング対応のエンタープライズ向け
HiveMQエンタープライズ機能豊富・クラウドマネージド対応
AWS IoT CoreAWSサービスとの統合・マネージドサービス

ESP32でのMQTT実装例

ESP32のArduinoフレームワークでPubSubClientライブラリを用いた実装例です。

#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "broker.example.com";
const int mqtt_port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Client")) {
      client.subscribe("device/ESP32-001/command");
    } else {
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();

  // 温度データをパブリッシュ(1秒ごと)
  static unsigned long lastMsg = 0;
  if (millis() - lastMsg > 1000) {
    lastMsg = millis();
    float temperature = 25.3; // センサー読み取り値
    String payload = "{\"temperature\":" + String(temperature) + "}";
    client.publish("factory/line1/sensor/temperature", payload.c_str());
  }
}

セキュリティのポイント

  • TLS/SSL暗号化: ポート8883でMQTT over TLSを使用し、通信を暗号化する
  • クライアント証明書認証: ユーザー名/パスワードより強固な認証として証明書・PKIを活用
  • ACL(アクセス制御リスト): ブローカー側でパブリッシュ・サブスクライブ可能なトピックをクライアントごとに制限
  • LWTを活用した異常検知: デバイスの不正切断を素早く検知してアラートを発行

KeepAliveとセッション管理

KeepAlive値は接続を維持するための定期pingの間隔です。接続時に秒単位で指定し、この1.5倍の時間内に通信がないとブローカーは切断とみなします。電波が不安定な環境では適切な値(30〜60秒程度)に調整することが重要です。

他技術との比較

比較項目MQTTCoAPAMQPHTTP/HTTPS
プロトコルモデルPub/SubRequest/ResponsePub/Sub + QueueRequest/Response
トランスポートTCPUDPTCPTCP
ヘッダサイズ最小2バイト4バイト数十バイト〜数百バイト〜
双方向通信△(Observe)△(WebSocket併用)
信頼性制御QoS 0/1/2CON/NON強力なACKTCPに依存
向き軽量IoT全般制約機器エンタープライズWeb全般

MQTTは軽量さと実装の容易さ、豊富なクライアントライブラリ(C/Python/Java/JavaScript等)のエコシステムにより、IoT分野で最も広く採用されているプロトコルです。MQTT-SNはUDP上でMQTTに近い機能を提供し、さらに制約の強いセンサーデバイスへの対応を可能にしています。

関連用語

参考リンク