プロトコル

Sparkplug Bとは?MQTT上の産業データ規約と状態管理を実装目線で解説

Sparkplug Bとは?MQTT上の産業データ規約と状態管理を実装目線で解説

Sparkplug Bは、MQTTの上に産業データの並べ方と状態の扱いを決めた規約です。仕様書はEclipse Foundationが配布するSparkplug 3.0.0(2022年11月16日版・全141ページ)で、2023年11月にISO/IEC 20237として国際規格になったと同財団が公表しています。定めているのはトピックの5要素、9種のメッセージ型、Protocol Buffersのペイロード、セッション状態の4点で、通信そのものはMQTTのままです。この記事では素のMQTTとの差、SCADAやPLCと組むときのエッジノードの置き場所、入れると損をする構成までを仕様書の条項に沿って整理しました。

まとめ|Sparkplug B導入で最初に決まる二つの設計

Sparkplug Bを入れると決めた瞬間、設計の焦点は次の2点に集約されます。

1点目は誰をPrimary Host Applicationにするか。1台のエッジノードが指定できるPrimary Hostは1つだけで、これがオフラインを表明した瞬間、エッジノードは現在のブローカーを切断して次のサーバへ移ります。上位のどれが止まったら現場が動き方を変えるかを先に決めない限り、冗長化の構成が書けません。

2点目はメトリック名を誰が決めるか。BIRTHで宣言した名前と型が、そのまま上位アプリとの契約になります。名前の変更はNBIRTHのやり直しを伴い、タグを1つ増やすたびに受け側へ波及する。命名権を発注側が握るか機器ベンダーに委ねるかで、運用開始後の手間が変わります。

Sparkplug Bとは何か|素のMQTTに足りない三つの規定を埋める仕様

MQTTが決めるのは「どう運ぶか」だけで、トピックの文字列にもペイロードの中身にも規定はありません。Pub/Subの仕組みやQoSレベルの選び方はMQTTとは?Pub/Subの仕組み・QoS・MQTT 5.0の実装からHTTPとの使い分けまで実装者向けに解説で扱っています。Sparkplug Bはその上にトピック構造・メッセージ種別・符号化の三つを足し、別ベンダーのクライアント同士が事前調整なしにデータを読める状態を作ります。

spBv1.0で始まるトピック名前空間の5要素と予約文字の制約

トピックはspBv1.0/group_id/message_type/edge_node_id/[device_id]の形に固定されます。先頭のspBv1.0はペイロード定義Bを示し、旧来のAは仕様書4.1.1で非推奨と明記されました。

group_idとedge_node_idの組み合わせは、MQTTインフラ全体で一意でなければなりません。両IDともUTF-8文字列ですが、プラス記号・スラッシュ・シャープの3文字は使えない。ワイルドカードと階層区切りに衝突するためです。設備番号をそのままIDに流用するとスラッシュが混ざりやすい。

device_idは任意要素で、付く先が決まっています。DBIRTH・DDEATH・DDATA・DCMDには必ず付き、NBIRTH・NDEATH・NDATA・NCMD・STATEには付けてはならない。IDは全メッセージに乗るので短くします。

NBIRTHからSTATEまで9種のメッセージ型が持つ役割分担

メッセージ型は9種類で固定です。独自の型名は足せません。

型 送る側 役割
NBIRTH エッジノード 全メトリックの宣言
NDEATH ブローカー代理 ノード切断の通知
DBIRTH エッジノード 配下デバイスの宣言
DDEATH エッジノード デバイス断の通知
NDATA エッジノード ノード値の変化報告
DDATA エッジノード デバイス値の変化報告
NCMD ホストアプリ ノードへの書き込み
DCMD ホストアプリ デバイスへの書き込み
STATE ホストアプリ 上位の稼働状態

押さえるべきは、NDEATHだけ送信主体がブローカーである点です。エッジノードは接続時にWillとして預け、配信はブローカー側。死亡通知に「なぜ落ちたか」は入りません。

Protocol Buffersで定義されたペイロードとメトリック構造の中身

ペイロードはGoogle Protocol Buffersのバイナリです。仕様書はJSON表記で例示しますが、流れるのはJSONではありません。最上位のPayloadはtimestamp・metrics配列・seq・uuid・bodyを持ち、各Metricはname・alias・timestamp・dataType・valueに加えmetadataとpropertiesを任意で持てます。

値の型は整数・浮動小数・真偽値・文字列に加え、表形式のDataSetと構造体に当たるTemplateまで定義済み。温度1点の値もポンプ1台分の構造体も、同じ配列に混在させられます。

符号化とデコードの自作は不要です。Eclipse Tahuが参照実装をC・Java・JavaScript・Pythonの4言語で出しており、最新リリースは仕様本体と同じ2022年11月16日の1.0.0。スキーマ定義も仕様書に全文が載っています。参照実装を使わずPythonの素のMQTTクライアントから組む場合の作法は、paho-mqtt 2系のループ方式と再接続の実装で扱っています。

素のMQTTとの差|WillとbdSeqで組む切断検知とセッション同期の仕組み

Sparkplug Bの本体は、実のところ状態管理の規定にあります。Willとretainの使い方を細かく縛り、「今どのノードが生きていて、どの値が信用できるか」を購読側が単独で判定できるようにした。素のMQTT運用と最も差が出る部分です。

NDEATHをWillに登録しbdSeqで前後関係を突き合わせる手順

エッジノードはCONNECTのWillに、NDEATHトピックとペイロードを登録します。Will QoSは1、Will Retainはfalse。載せるメトリックはbdSeqただ1つで、型はINT64です。

続けて公開するNBIRTHには、同じ値のbdSeqを入れます。ホストアプリはこの一致を見て、届いたNDEATHがどの接続の通知かを判定する。値は0から始めCONNECTのたびに1増やし、255の次は0へ戻します。

この仕組みが要るのは、再接続の順序が保証されないからです。NBIRTHを出した後に前回分のNDEATHが遅れて届くことがあり、bdSeqが古ければ無視してよいと機械的に判定できる。自発的に切断する場合は、v3.1.1ならDISCONNECT送信前に自分でNDEATHを公開する義務があり、v5.0では理由コードで代替できます。

seq番号0〜255の巡回で欠落を検知しRebirthを要求する流れ

NBIRTH・DBIRTH・NDATA・DDATA・DDEATHの各ペイロードには、0〜255を巡回するseqが必ず入ります。NBIRTHが0、以降そのノードが出すメッセージごとに1ずつ増え、255の次は0。番号はノード単位で通し、配下デバイスの分も同じ列に混ぜます。

ここに例外が1つ。NDEATHはseqを含めてはならない。ブローカーが代理で送る以上、送信時点の番号を事前に埋められないためで、仕様書は明示的な禁止条項として書いています。

番号が飛んだと気づいたホストアプリは、NCMDでRebirth用のメトリックにtrueを書き込みます。エッジノードはNBIRTHとDBIRTHを出し直し、購読側は状態を作り直す。この再同期の入口はNBIRTHに必ず含める義務があり、初期値はfalseです。

STATEトピックのJSON化と2.2実装との非互換で起きる事故

上位側の生死は、STATEトピックで表明されます。3.0.0でのトピックはspBv1.0/STATE/[sparkplug_host_id]、QoSは1、retainはtrue。ペイロードはJSON UTF-8で、online(真偽値)とtimestamp(エポックミリ秒)の2キーです。Willにはonline=falseの同じJSONを登録します。

ここが移行時の落とし穴です。2.2仕様のWill TopicはSTATE/scada_host_idで、ペイロードはUTF-8文字列のOFFLINEでした。接頭辞のspBv1.0が無く、JSONでもない。両世代を同じブローカーに混ぜると購読トピックが噛み合わず、噛み合ってもJSONの解析で落ちます。

更新できるのは、たいてい上位アプリか下位のエッジノードの一方だけです。混在期間が出る前提で、どちらの世代に寄せるかを先に決める。上位監視側の構成はSCADAとは?スキャダの仕組みとPLC・DCS・MESとの役割分担を実装目線で解説にまとめてあります。

aliasでDATAを縮める設計と名前復元を担う側の切り分け

産業用のメトリック名は「工場A・ライン2・充填機・主軸温度」のように長くなります。BIRTHでnameとaliasの両方を宣言させ、以降のNDATA・DDATA・NCMD・DCMDではaliasだけを載せnameを除外させる。数十バイトの名前が数バイトの整数に変わり、送信量が減ります。

代償は、BIRTHを取り逃した購読者が名前を復元できないことです。対応表の共有だけが送信量削減の前提になる。途中参加のクライアントをどう扱うかは実装側で決めます。

選択肢は二つ。ブローカー側で復元させるか、購読アプリ側でBIRTHを保持するかです。EMQXはspb_decodeを組み込み関数として持ち、BIRTHで宣言されたaliasとnameの対応をセッション単位で保持してDATA側の名前を戻します(2026年8月時点の同社ドキュメント)。なお、Rebirth用のメトリックにaliasを付けてはいけません。名前を知らない購読者からでも再同期を要求させるためです。

実装で最初に詰まる規定|QoSとretainとClean Sessionの固定値

Sparkplug Bは、MQTTの設定値のうち通信品質に関わる部分をほぼ固定します。「うちはQoS 2で確実に送る」という方針は、そのままでは仕様に適合しません。自由度がどこまで残るかを先に把握すると、ブローカー選定が早く済みます。

全メッセージがQoS0でretainなしという原則と二つの例外

NBIRTH・DBIRTH・NDATA・DDATA・NCMD・DCMD・DDEATHは、すべてQoS 0かつretainフラグfalseで公開します。例外は2つだけです。

メッセージ QoS retain
NBIRTH・DBIRTH 0 false
NDATA・DDATA 0 false
NCMD・DCMD 0 false
DDEATH 0 false
NDEATH(Will) 1 false
STATE 1 true

QoS 0で取りこぼしを許すのは、欠落の検知をseq番号に任せているからです。QoS 1の重複配信やQoS 2の往復より、番号の不連続からRebirthで作り直すほうが速い。レベルごとの再送挙動はMQTT QoSとは?レベル0・1・2の違い・仕組み・選び方を解説に整理しています。

Clean Sessionをtrue固定にする規定と蓄積をどこで持つか

エッジノードのCONNECTでは、v3.1.1ならClean Sessionをtrue、v5.0ならClean Start=trueかつSession Expiry Interval=0が義務です。ブローカー側にセッションを残さない、と言い切っている。

この一行が蓄積の設計を決めます。切断中のデータをブローカーのキューに溜めて再送させる作りは選べません。溜めるならエッジノード側です。仕様書もPrimary Hostのオフライン中はエッジで保持し、オンライン表明を受けて送り直す例を挙げています。

設計判断は、エッジ側のストレージ容量と保持期間の見積もりに落ちます。回線が1日切れても持つのか、1時間で溢れるのか。切れ方は下位ネットワークの構成に左右されるため、産業用ネットワークとは?フィールドバスと産業用Ethernetの分類・規格選定を実装目線で解説と併せて見ます。

Sparkplug Aware MQTT Serverが持つBIRTH保存先の仕様

仕様書10.1.4は、適合サーバより一段強い「Sparkplug Aware MQTT Server」を定義します。通過するNBIRTHとDBIRTHを保存し、$sparkplug/certificates/spBv1.0/G1/NBIRTH/E1のような専用トピックへretain trueで出し直すサーバです。

気をつけたいのは、保存されるのが公開当時のBIRTHそのものである点です。その後NDATAで値が変わっても更新されません。取り出せるのは構造とalias対応であって現在値ではないと、仕様書も明記しています。

この機能の有無は製品で分かれます。汎用ブローカーはSparkplugを解釈せず、途中参加クライアントの面倒は購読側で見る。製品ごとの違いと構築手順はMQTTブローカーとは?仕組み・比較・構築手順を解説で比較しています。

SCADA・PLC連携での配置|エッジノードの置き場所と変換の設計

実装作業の大半は、プロトコル対応ではなく変換層の設計です。PLCのタグ、OPC UAのノード、既存SCADAのポイント名をどこへ写すか。決めきれないまま着手すると、BIRTHの宣言内容が固まらず手戻りします。

PLCのタグをメトリック名へ写すときの命名規則と型の対応付け

PLCから読んだ値は、そのままではメトリックになりません。アドレスに意味を与える命名と、Sparkplugの型への写像が要ります。D100が符号付き16ビットか32ビットの下位語かで、Int16とInt32のどちらを宣言するかが変わる。

命名は階層を持たせるのが実務的です。仕様書は文字種を強く縛らないため、拠点・ライン・設備・信号の4段で組む例が多い。宣言済みの名前の変更はNBIRTHのやり直しを伴うので、命名規則は運用開始前に凍結します。

PLC側で値をどう取り出すかは、Sparkplug以前の問題として別に決めます。収集方式の選び分けとタグ設計はPLCのデータ収集|四方式の選び分けとタグ設計・欠測対策を実装目線で解説で扱いました。

OPC UAサーバとSparkplugエッジノードの役割分担の決め方

既にOPC UAサーバが立つ現場では、二重投資に見えることがあります。実際には守備範囲が違う。OPC UAは情報モデルで機器の意味構造を表現し、クライアントが要求して読む形が基本です。Sparkplug Bは変化時だけ押し出す形で、モデルの表現力を持ちません。

組み合わせるなら、OPC UAクライアントとして読み、Sparkplugエッジノードとして公開する変換プロセスを1つ置きます。情報モデルを階層へどこまで写すかが焦点で、全ノードを機械展開すると数千メトリックのBIRTHが生まれて破綻する。OPC UAとは?情報モデルとOPC Classicとの違い・採用判断を実装目線で解説で情報モデル側を確認し、上位が本当に要る点だけを選んでください。

複数ブローカー構成での主系切り替えとサーバ移動指示の使いどころ

エッジノードは複数のMQTTサーバをリストで持てますが、同時に接続するのは1台です。切り替えの引き金はPrimary HostのSTATEで、オフライン表明を受けたら現在のサーバを切って次へ移ります。

ホスト側から移動を促す道もあります。NCMDでNext Server用のメトリックを書き込むと、エッジノードは次のサーバへ移る。計画停止で使う指示です。

Primary Hostは1エッジノードにつき1つだけ、という制約は冗長化の設計に効きます。2台目以降は監視専用かホットスタンバイとしてなら並べられるものの、切り替え判定の主体にはなれない。冗長化のつもりで2つ設定する構成は仕様の想定外です。

採用条件と見送り場面|Sparkplug Bを入れて損をしない境界線

Sparkplug Bは万能の共通言語ではありません。得るのは相互運用性と状態の明確さ、払うのは変換層の実装と運用ルールの固定化。どちらが上回るかは構成で決まります。

Sparkplug Bの採用に踏み切ってよい三つの条件と見極め方

次の3条件のうち2つ以上に当てはまるなら、入れる価値がある。

  • 複数ベンダーの機器と複数拠点があり、同じデータを上位ごとに別形式で作り直している
  • 回線が細いか切れる環境で、切断検知と復旧の仕組みを自作したくない
  • 上位の受け側を後から増やす予定があり、その都度の個別接続を避けたい

3つとも効いてくるのは接続の本数が増えてからです。拠点が1つで上位も1つなら、どの条件も成立しません。将来増える予定があるのかを、稟議の文言ではなく計画の日付で確認してから決めてください。

Sparkplug Bを見送るべき四つの構成と代わりに選ぶ手段

次の構成では採用しません。条件付きで言い切ります。

第一に、単一ベンダーのSCADAで閉じた構成。純正の収集機構が状態管理まで持つため、Sparkplugを挟むと変換層が1段増えるだけで、見返りが発生しません。

第二に、要求応答が主体の用途。履歴データの範囲取得は守備範囲外で、仕様に問い合わせの手段がありません。NCMDとDCMDは書き込みの指示です。素直にHTTP APIかOPC UAが早い。

第三に、画像や波形など大きなデータを運ぶ経路。bodyにバイト列を入れられても、QoS 0とretainなしを前提にした設計とは噛み合いません。

第四に、センサー数点を1拠点から送るだけの構成。BIRTHとDEATHの状態機械を作る工数は、素のMQTTとJSONで組む場合との差では回収できません。この規模なら自前のトピック設計のほうが保守も楽です。

受託開発で外部に出す実装範囲と社内に残しておく運用範囲の線引き

線引きの基準は「変わる頻度」に置くと収まりがよい。外に出しやすいのは、protobufの符号化、BIRTHとDEATHの状態機械、エッジ側の蓄積と再送、ブローカー構成、上位への取り込み。一度作れば構造は変わりません。

社内に残すのは、メトリックの命名規則、機器側の設定値、Primary Hostをどれにするかの判断。製造ラインの都合で動く部分で、外部に固定させると変更のたびに費用が発生します。

切り分けの設計から実装まで相談したい場合は、AI/IoTソリューションで工場データ収集基盤の受託開発を扱っています。既存のPLCとSCADAを残したまま上位へ流す構成の検討からご相談ください。

よくある質問

導入検討でよく挙がる質問を、仕様書の記述に沿って整理します。

Sparkplug AとSparkplug Bの違いは何ですか?

ペイロードの符号化方式が違います。Aはトピック接頭辞がspAv1.0で、初期の実装が用いた形式が土台。BはspBv1.0で、メトリックにaliasやDataSet、Templateを持てるProtocol Buffers定義です。3.0.0仕様書にAの定義は残るものの4.1.1で非推奨と明記され、新規実装でAを選ぶ理由はありません。トピック構造と状態管理の規定は共通です。

Sparkplug Bは普通のMQTTブローカーでそのまま使えますか?

使えます。Sparkplug Bはクライアント間の取り決めで、ブローカーに特別な機能を要求する仕様ではありません。MQTT v3.1.1またはv5.0に適合し、QoS 0と1、retainフラグ、Will Messageを正しく扱えるサーバなら動きます。ただしNBIRTHとDBIRTHを専用トピックへ保存するSparkplug Aware MQTT Serverの機能は追加要件で、対応は製品ごとに分かれる。途中参加のクライアントにalias対応表を配りたい場合だけ選定条件になります。

MQTT 5.0でもSparkplug Bは使えますか?

3.0.0からv5.0が正式に対象へ入りました。エッジノードはCONNECTでClean Start=trueかつSession Expiry Interval=0を設定します。v3.1.1のClean Session=trueと同じ意図で、ブローカー側にセッションを残さないためです。自発的な切断時の扱いにも差があり、v5.0ではDisconnect with Will Messageの理由コードで、自前でNDEATHを公開する手順を省けます。

Sparkplug Bのペイロードは圧縮されますか?

3.0.0の仕様本文に圧縮方式の規定はありません。削減は二つの仕掛けで行います。一つはProtocol Buffersのバイナリ符号化で、JSONのようなキー名の反復が消えること。もう一つはaliasで、BIRTH以降のDATAでは長いメトリック名が整数1つに置き換わることです。変化のあった値だけを送る運用も前提のため、周期的な全点送信より総量が下がります。

Sparkplug 4.0はいつリリースされますか?

2026年8月時点で、Eclipse Foundationのプロジェクトページに載る最新リリースは3.0.0(2022年11月16日)で、4.0.0は開発中の扱いです。公開日の確約は出ていません。実装するなら3.0.0を対象にし、2.2世代が現場に残っていないかを先に棚卸ししておくと実害を防げます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.06 テックブログ 大和証券の不正アクセスと約11万人分の口座番号:問い合わせ管理の委託先に残さない設計
  2. 2026.10.06 テックブログ 焼肉きんぐの不正アクセスと1,078万件の会員情報|全件規模の流出を防ぐAPIとログの点検
  3. 2026.10.06 テックブログ 原子力研究開発機構の不正アクセスと身分証画像の漏えい|研究支援サイトのファイル保管を点検する手順
  4. 2026.10.04 テックブログ デジタル庁GSSの不正アクセスと約24.6万件|CVSS中のVPN脆弱性を何で優先するか
  5. 2026.10.01 テックブログ AWS VPN Clientの使い方:6.x系のインストールとCLI・接続できない時の確認先

RELATED POSTS 関連記事

目次