本文从协议原理、消息结构、状态管理、数据序列化、性能指标和应用场景等多个维度,对标准 MQTT 协议与 Sparkplug B 工业数据规范进行系统性对比分析,为物联网架构师和开发者在技术选型时提供决策参考。


一、概述

在工业物联网(IIoT)领域,MQTT 凭借其轻量级、低带宽、高可靠的设计,已成为设备互联的事实标准消息协议。然而,标准 MQTT 本身仅定义了消息的传输机制,对应用层数据格式、设备状态管理和互操作性并未做出规定。这导致在工业场景中,不同厂商的设备往往采用各自的数据约定,形成「数据孤岛」,严重制约了系统的互操作性。

Sparkplug 正是在这一背景下诞生的。它是由 Eclipse Foundation 托管的开放规范;Eclipse Tahu 提供参考实现。Sparkplug B 基于 MQTT,定义了 Protobuf Payload、标准化主题命名空间以及 Birth/Death 状态管理机制,为工业物联网建立可互操作的数据交换约定。

核心观点:Sparkplug B 与 MQTT 并非竞争关系,而是互补关系。MQTT 是"应用层消息协议",Sparkplug B 是"应用层数据规范"。

封面:MQTT vs Sparkplug B 总览


二、MQTT 协议深度解析

2.1 协议定位与设计哲学

MQTT 最初于 1999 年提出,面向低带宽、不稳定网络上的轻量消息传输。MQTT 3.1.1 于 2014 年成为 OASIS 标准,并于 2016 年发布为 ISO/IEC 20922:2016;MQTT 5.0 于 2019 年成为 OASIS 标准,引入了原因码、消息过期、用户属性、会话过期等能力。

MQTT 的设计哲学可以概括为三个关键词:

  • 轻量级:最小报文仅 2 字节,极低的网络开销
  • 解耦:发布者(Publisher)与订阅者(Subscriber)通过 Broker 完全解耦
  • 可靠:支持 QoS 0/1/2 三级服务质量,满足不同可靠性需求

2.2 通信模型与架构

MQTT 采用经典的发布/订阅(Publish/Subscribe)模型,核心角色包括:

角色职责
Publisher(发布者)向指定 Topic 发布消息,无需知道订阅者是谁
Subscriber(订阅者)订阅感兴趣的 Topic,接收匹配的消息
Broker(消息代理)接收发布者的消息,按 Topic 路由分发给订阅者

MQTT 协议架构与通信模型

2.3 消息结构详解

MQTT 报文由三个部分组成:固定报头(Fixed Header)可变报头(Variable Header)有效载荷(Payload)

MQTT 消息结构解析

固定报头(2-5 字节):

  • 报文类型(4 bits):MQTT 3.1.1 定义 14 种控制报文,MQTT 5.0 增加 AUTH,共 15 种
  • 标志位(4 bits):如 DUP、QoS、RETAIN 等控制标志
  • 剩余长度(1-4 字节):采用变长字节整数编码,最大值为 268,435,455;它表示可变报头与 Payload 的总长度,不等于可用 Payload 上限

可变报头:取决于报文类型,通常包含:

  • 协议名与协议级别(CONNECT 报文)
  • 主题名(PUBLISH 报文)
  • 报文标识符(QoS > 0 时需要)

有效载荷

  • 可选字段,承载应用层数据
  • 内容格式完全由应用层决定(JSON、XML、二进制等)
  • MQTT 本身不做任何数据格式约束

2.4 核心特性

QoS(Quality of Service)分级

QoS 等级语义报文交互适用场景
QoS 0最多一次(At most once)1 次发送,无确认高频率、可容忍丢失的数据
QoS 1至少一次(At least once)发送 + PUBACK 确认要求可靠但可容忍重复的场景
QoS 2恰好一次(Exactly once)PUBLISH/PUBREC/PUBREL/PUBCOMP 四个控制报文单个 MQTT 传输链路上不能重复处理的消息

QoS 保证作用于相邻 MQTT 客户端与服务端之间,不自动等同于端到端业务事务的“恰好一次”。

保留消息(Retained Message):Broker 保留指定 Topic 的最后一条消息,新订阅者可立即获取,无需等待下一次发布。

遗嘱消息(Last Will and Testament, LWT):客户端连接时预设的"遗言",当客户端异常断开时,Broker 自动将其发布到指定 Topic,实现离线通知。

会话保持(Session Persistence):MQTT 3.1.1 已可通过 Clean Session = 0 保留会话状态;MQTT 5.0 用 Clean StartSession Expiry Interval 对其进行了更明确、可控的表达。离线消息能否缓存还取决于订阅、QoS、会话配置与 Broker 策略。

2.5 MQTT 的局限性

尽管 MQTT 在传输层面表现卓越,但在工业物联网的实际应用中,开发者很快会遇到以下痛点:

  1. 数据格式不统一:各厂商自定义 JSON 结构,互操作性差
  2. 状态管理薄弱:LWT 仅支持异常断线通知,无法构建完整的设备状态视图
  3. 缺乏数据建模:没有标准的数据类型系统和设备建模机制
  4. 缺少统一 Schema:即使使用 JSON,也需要另行约定字段、类型、单位和兼容策略
  5. 编码效率不固定:若采用冗长 JSON,字段名和文本编码会增加消息体积
  6. 主题命名无规范:各厂商自行定义 Topic 结构,缺乏统一的命名约定

三、Sparkplug B 协议深度解析

3.1 协议定位

Sparkplug 是 Eclipse Foundation 托管的开放规范,早期版本由 Cirrus Link Solutions 推动,3.0 起按 Eclipse Foundation Specification Process 管理。Eclipse Tahu 是其参考实现项目。Sparkplug B 的目标是:在 MQTT 之上,为工业物联网定义标准化的数据交换与会话状态语义

Sparkplug B 不是替代 MQTT,而是:

  • 使用 MQTT 作为底层消息协议(支持 MQTT 3.1.1 和 MQTT 5.0)
  • 使用 Google Protocol Buffers(Protobuf)作为数据序列化格式
  • 定义标准化的主题命名空间(Topic Namespace)
  • 引入 Birth/Death 证书机制实现完整的设备生命周期管理
  • 建立标准化的数据类型系统和 Metric 数据模型

3.2 系统架构

Sparkplug B 的系统架构包含三类核心角色:

角色说明主要职责
Host Application主机应用 / SCADA 系统接收设备数据、管理节点状态、下发指令
Edge Node边缘节点 / 网关汇聚多个设备数据、维护设备层次关系、执行本地逻辑
Device终端设备 / 传感器采集物理量、执行控制指令、上报状态变化

Sparkplug B 协议架构与数据流

3.3 主题命名空间

Sparkplug B 对 MQTT Topic 进行了严格的结构化定义,格式为:

spBv1.0/{Group_ID}/{Message_Type}/{Edge_Node_ID}/{Device_ID}
  • spBv1.0:Sparkplug 版本标识(固定前缀)
  • {Group_ID}:逻辑分组标识(如产线编号、区域编号)
  • {Message_Type}:消息类型(NBIRTH、NDEATH、DBIRTH、DDEATH、NDATA、DDATA、NCMD、DCMD)
  • {Edge_Node_ID}:边缘节点唯一标识
  • {Device_ID}:设备唯一标识(可选,DBIRTH/DDATA/DDEATH/DCMD 需要)

Host 的状态消息使用独立格式:

spBv1.0/STATE/{Sparkplug_Host_ID}

这种标准化主题便于订阅过滤和组件发现,但 Group、Edge Node、Device、Metric 的命名及业务语义仍需项目治理,并不会自动消除所有跨厂商冲突。

3.4 消息类型(证书机制)

Sparkplug B 定义了一套完整的证书(Birth Certificate)机制来管理设备和节点的生命周期:

消息类型全称触发时机说明
NBIRTHNode Birth边缘节点上线节点连接时发送,包含节点所有 Metric 的初始状态
NDEATHNode Death边缘节点离线异常断开时由 Broker 按 Will 发布;计划下线时由 Edge Node 主动发布
DBIRTHDevice Birth设备上线边缘节点下的设备首次报告时发送
DDEATHDevice Death设备离线设备从边缘节点断开时发送
NDATANode Data节点数据变化边缘节点自身的 Metric 数据变化时上报
DDATADevice Data设备数据变化设备的 Metric 数据变化时上报
NCMDNode Command节点控制指令Host 向边缘节点下发控制命令
DCMDDevice Command设备控制指令Host 向设备下发控制命令
STATEState主机状态Host 应用上线/离线时的状态通知

这套证书机制使得系统能够精确知道:

  • 当前有哪些节点/设备在线
  • 每个设备支持哪些 Metric(指标)
  • 节点/设备何时建立或结束 Sparkplug 会话
  • 数据是否完整(通过序列号检测丢包)

3.5 Protobuf 消息结构

Sparkplug B 的核心 Payload 采用 Google Protocol Buffers 定义,具备强类型、紧凑编码、跨语言支持等优势。

Sparkplug B 消息结构 (Protobuf 编码)

Payload 结构

message Payload {
  uint64 timestamp = 1;          // 消息时间戳(毫秒)
  repeated Metric metrics = 2;   // 指标数据数组
  uint64 seq = 3;                // 序列号(0-255,循环递增)
  string uuid = 4;               // 可标识 body 所采用的自定义编码或 Schema
  bytes body = 5;                // 原始二进制数据(扩展用途)
}

Metric 结构

message Metric {
  string name = 1;               // 指标名称
  uint64 alias = 2;              // 别名(用于减少传输开销)
  uint64 timestamp = 3;          // 指标时间戳
  uint32 datatype = 4;           // 数据类型(枚举值)
  bool is_historical = 5;        // 是否为历史数据
  bool is_transient = 6;         // 是否为瞬态数据
  bool is_null = 7;              // 值是否为 null
  MetaData metadata = 8;         // 元数据(单位、描述等)
  PropertySet properties = 9;    // 自定义属性
  // value 使用 oneof 定义,确保类型安全
  oneof value {
    uint32 int_value = 10;       // 32位整型
    uint64 long_value = 11;      // 64位整型
    float float_value = 12;      // 32位浮点
    double double_value = 13;    // 64位浮点
    bool boolean_value = 14;     // 布尔型
    string string_value = 15;    // 字符串
    bytes bytes_value = 16;      // 二进制
    DataSet dataset_value = 17;  // 数据集
    Template template_value = 18; // 模板
  }
}

模板机制(Template)

Sparkplug B 支持 Template(模板)类型。模板定义只能出现在 NBIRTH 中;模板实例通过 template_ref 引用定义。NBIRTH/DBIRTH 中的实例必须包含定义中的全部成员,NDATA/DDATA 中则可以只发送发生变化的成员。

数据类型系统

Sparkplug B 3.0 的 DataType 枚举包含 35 个值(含 Unknown),覆盖常见标量、复合类型和数组:

类别数据类型
整数Int8、Int16、Int32、Int64、UInt8、UInt16、UInt32、UInt64
浮点Float、Double
布尔Boolean
字符串String、Text
二进制Bytes、File
时间DateTime
复合DataSet、Template、PropertySet、PropertySetList
数组Int8/16/32/64Array、UInt8/16/32/64Array、FloatArray、DoubleArray、BooleanArray、StringArray、DateTimeArray
其他UUID、Unknown

四、核心对比分析

4.1 能力雷达对比

从八个关键维度评估 MQTT 和 Sparkplug B 的能力差异:

MQTT vs Sparkplug B 能力雷达图

图中分数为作者的定性示意,不是协议标准评分或可复现基准测试结果。

解读

  • 带宽效率:MQTT 只规定传输,效率取决于应用 Payload;Sparkplug B 有 Birth 消息和 Payload 包装开销,但数据阶段可利用 Protobuf 与 Metric Alias 减少重复字段
  • 状态感知:Sparkplug B 的 Birth/Death 证书机制实现完整的设备生命周期管理,大幅领先 MQTT 的 LWT
  • 互操作性:Sparkplug B 统一了 Topic、Payload 和会话状态语义,可显著降低集成成本;真正的业务语义一致性仍依赖建模、命名治理和兼容性测试
  • 数据建模:Sparkplug B 提供标准类型、Metric、Alias、DataSet 和 Template;MQTT 本身不规定业务数据模型
  • 安全性:Sparkplug B 继承 MQTT 基础设施的 TLS、认证和 Broker ACL 等能力,本身不是加密协议
  • 易用性:MQTT 简单灵活,学习成本低;Sparkplug B 规范较复杂,需要理解证书机制和数据类型系统
  • 扩展性:MQTT 的 Topic 自由度高,扩展灵活;Sparkplug B 的标准化命名空间在扩展时有一定约束
  • 实时性:两者基于相同的 MQTT 协议传输,实时性表现基本一致

4.2 状态管理机制对比

状态管理是工业物联网的核心诉求之一。系统需要实时掌握每个设备的在线状态和健康状况。

状态管理机制对比:MQTT 遗嘱 vs Sparkplug B 证书

MQTT 遗嘱消息(LWT)的局限

  1. 仅在异常断开时触发:客户端正常断开(发送 DISCONNECT 报文)不会触发 LWT
  2. 正常下线需应用主动通知:客户端发送 DISCONNECT 时不会触发 Will,若业务需要“计划下线”状态,必须另行发布消息
  3. 缺少设备完整状态信息:LWT 仅携带一条预设消息,不包含设备的完整 Metric 列表
  4. 不支持设备层级关系:无法表达"边缘节点在线但某个子设备离线"的复杂状态

Sparkplug B 证书机制的优势

  1. 统一表达离线状态:异常断开由 Broker 发布 NDEATH Will,计划下线由 Edge Node 主动发布 NDEATH;STATE 用于表达 Sparkplug Host 的在线/离线状态。仅凭 NDEATH 本身通常不能判断离线原因
  2. 完整的设备状态快照:NBIRTH 和 DBIRTH 消息包含节点/设备的全部 Metric 定义,Host 在收到后即可构建完整的设备数据模型
  3. 支持设备层级关系:边缘节点(Edge Node)可以管理多个设备(Device),通过 DBIRTH/DDEATH 精确追踪每个子设备的状态
  4. 会话连续性检查seq 可发现消息序列缺口,bdSeq 关联 Birth/Death 会话;连接存活仍依赖 MQTT Keep Alive、Will 和 Broker 行为,Sparkplug 不要求额外的周期业务心跳

4.3 数据序列化对比

数据序列化方式直接影响消息体积、传输效率和解析性能。

数据序列化方式对比

JSON(MQTT 常见)

优点缺点
人类可读,调试方便冗余字段名重复传输,浪费带宽
语言无关,生态丰富若没有 JSON Schema 等额外约束,字段类型和语义容易漂移
开发调试简单文本编码效率低,二进制数据需 Base64
解析开销大,尤其在大数据量时

Protobuf(Sparkplug B)

优点缺点
二进制编码通常比冗长 JSON 更紧凑不可直接阅读,需工具解码
Schema 和生成代码可增强类型约束需要预定义 Schema(.proto 文件)
跨语言支持(C/C++/Java/Python/Go/JS 等)调试相对复杂,需要专用工具
向后兼容,支持字段增删
解析速度快,CPU 占用低

不能脱离数据模型、库实现和测试环境给出固定压缩倍数或耗时倍数。对于少量单值数据,Sparkplug 包装字段可能占比较高;对于包含大量重复字段名的 JSON,Protobuf 加 Metric Alias 通常更有优势。可靠的对比应公开:

  • 完整 JSON 与 Sparkplug Payload 样本
  • 是否计算 MQTT Topic、固定/可变报头与 TLS 开销
  • 是否使用 Metric Alias、批量上报和压缩
  • 客户端库、语言、硬件、消息频率与 QoS

4.4 协议层次架构对比

理解两者的协议层次关系,是正确选型的关键。

协议层次架构对比

MQTT 位于 OSI 模型的应用层(第 7 层),直接基于 TCP 传输层(第 4 层)运行,是一套完整的应用层消息协议。

Sparkplug B 则是一个更高层的应用层规范,它:

  • 使用 MQTT 作为传输协议
  • 在 MQTT 之上定义了数据格式(Protobuf)
  • 规定了主题命名空间的结构
  • 定义了设备生命周期管理的语义

因此,Sparkplug B 是"MQTT + Protobuf + 规范"的组合,而不是独立的传输协议。

4.5 性能评估方法

Sparkplug B 的性能不是一个固定倍数,主要取决于数据阶段节省的重复字段,能否抵消 Birth、状态管理和 Payload 包装带来的额外开销。

更可能受益的情况:指标数量多、更新频繁、JSON 字段名长、启用 Metric Alias、可以批量发布。

需要谨慎评估的情况:单次只发一个很小的值、节点频繁重连、设备资源极小、网络并非原生 IP/TCP,或现有二进制 Payload 已经很紧凑。

网络边界:Sparkplug 3.0 要求 MQTT 3.1.1/5.0 客户端与相应基础设施,通常运行在 TCP/IP 上。LoRa 等非 IP 链路一般需要网关转换,不能因为“带宽受限”就直接推导出 Sparkplug 一定适用。


五、应用场景分析

5.1 MQTT 适用场景

MQTT 的轻量、灵活、易用特性,使其非常适合以下场景:

智能家居:门锁、温控器、照明系统的互联。MQTT 的简单性使得消费级 IoT 设备可以快速接入,Home Assistant 等开源平台均内置 MQTT 支持。

车辆遥测与云连接:位置、速度、能耗等数据可通过蜂窝网络上报云端。这里指后台遥测,不等同于对时延和安全有专门标准要求的 V2X 直连通信。

环境监测:温湿度、PM2.5、水质等传感器数据的周期性上报。QoS 1 可降低链路级丢失风险,但应用仍需处理重复消息、存储失败和端到端确认。

远程设备通知:自助终端、移动应用或边缘设备的状态与告警推送。涉及支付等高风险业务时,还必须满足支付行业标准、端到端鉴权、幂等和审计要求,不能仅凭 MQTT + TLS 判定安全。

消息推送:即时通知、告警推送。MQTT 的发布/订阅模型天然适合一对多的消息广播。

5.2 Sparkplug B 适用场景

Sparkplug B 的标准化、状态感知和互操作性,使其成为工业场景的理想选择:

智能工厂:产线设备的实时监控、MES 系统集成、OEE(设备综合效率)计算。Sparkplug B 可统一传输与状态语义,但 PLC、传感器、HMI 的业务标签仍需映射和验证。

能源管理:智能电网、油田数字化、新能源(风电/光伏)监控。能源系统对数据完整性和状态实时性要求极高,Sparkplug B 的证书机制确保系统始终掌握每个节点的健康状态。

楼宇自控(BAS):暖通空调(HVAC)、照明控制、安防集成。可利用 Group、Edge Node、Device 和分层 Metric 名称映射物理结构,但规范并未固定“楼宇 → 楼层 → 房间”的语义模型。

过程监控与上层集成:适合 SCADA、Historian、MES 等系统的数据采集和状态同步。是否用于闭环控制、联锁或安全功能,必须结合确定性、失效模式和功能安全要求单独评估。

预测性维护:振动传感器、温度传感器、电流互感器的持续监测。通过 NDATA/DDATA 的时序数据流,结合边缘计算,实现设备故障的早期预警。

5.3 选型决策矩阵

场景特征推荐方案
消费级 IoT、快速原型开发MQTT + JSON
设备种类单一、自研系统MQTT + 自定义格式
多厂商设备集成、互操作需求Sparkplug B
SCADA/Historian/MES 数据集成Sparkplug B
带宽成本敏感且有 IP/TCP 基础设施实测 MQTT 自定义二进制与 Sparkplug B 后再决定
需要离线状态感知的工业场景Sparkplug B
简单数据上报、无状态管理需求MQTT

六、选型建议

6.1 何时选择 MQTT?

选择标准 MQTT 的场景包括:

  • 项目处于初期阶段,需要快速验证概念,MQTT 的简单性可以大幅降低开发门槛
  • 系统由单一团队/厂商开发,数据格式可以完全自主约定,互操作性不是首要考量
  • 设备资源极度受限(如 8 位 MCU、KB 级 RAM),无法容纳 Protobuf 解析库
  • 场景对状态管理要求不高,仅需要简单的数据上报和指令下发
  • 现有系统已基于 MQTT 构建,迁移成本过高

6.2 何时选择 Sparkplug B?

选择 Sparkplug B 的场景包括:

  • 工业物联网项目,涉及多品牌、多类型设备的集成
  • 需要 SCADA/Historian/MES 集成,且所选产品已验证兼容 Sparkplug 3.0
  • 对设备在线状态有严格要求,需要实时掌握每个节点的健康状态
  • 带宽成本敏感,且已用真实 Payload 验证 Protobuf、Metric Alias 与批量策略确有收益
  • 追求长期可维护性,标准化的数据模型降低了系统演进的技术债务

6.3 迁移路径

对于已基于 MQTT 运行的系统,向 Sparkplug B 的迁移可以分阶段进行:

  1. 第一阶段:在现有 MQTT Broker 上引入 Sparkplug B 边缘节点网关,将原有设备通过网关接入 Sparkplug B 规范
  2. 第二阶段:新设备直接采用 Sparkplug B 协议,旧设备维持 MQTT 直至退役
  3. 第三阶段:全面迁移至 Sparkplug B,享受标准化带来的互操作和运维便利

七、总结

MQTT 和 Sparkplug B 在物联网协议生态中扮演着不同但互补的角色:

  • MQTT 是一款优秀的应用层消息协议,以其轻量、灵活、可靠的设计,在通用物联网领域获得了广泛采用。
  • Sparkplug B 是基于 MQTT 的工业级应用层规范,通过 Protobuf 编码、标准化主题命名空间和 Birth/Death 证书机制,针对工业物联网中的互操作性、状态管理和数据建模等核心痛点提供统一约定。

两者不是同一层面的竞争关系:MQTT 负责消息传输,Sparkplug 在其上增加工业数据与会话状态约定。工业项目也不应仅凭行业标签自动选择 Sparkplug;仍需结合现有生态、设备资源、网络条件、数据模型、兼容认证和运维能力评估。

在技术选型时,建议从业务需求出发:如果追求快速开发、灵活自定义,MQTT 是更直接的起点;如果需要统一 Topic、Metric 和状态生命周期,并且相关产品已验证兼容,Sparkplug B 值得优先评估。


参考资源

  • MQTT 3.1.1 规范 - OASIS
  • MQTT 5.0 规范 - OASIS
  • Sparkplug 规范与版本历史 - Eclipse Sparkplug
  • Sparkplug 3.0.0 规范 PDF - Eclipse Sparkplug
  • Eclipse Tahu 项目
  • ISO/IEC 20922:2016

更多推荐