[深入浅出MQTT]: v3.1.1与v5 的差异

[深入浅出MQTT]: v3.1.1与v5 的差异

MQTT v3.1.1 与 v5 完全相容,且提供许多Cluster 所需要的功能,如Shared Subscriptions、 User Properties等实用功能,且不会因为新增加功能造成效能低落的问题。

MQTT 起初是由 IBM 在 1999 年提出的,是针对 IoT 装置设计的 MQ,是属於发展许久的 MQ。主要设计的原则是:

  1. Simple implementation: 可以简单的被使用。
  2. Quality of Service data delivery: 提供不同程度的Data 传输品质。
  3. Lightweight and bandwidth efficient: 轻量化且高频宽的效能。
  4. Data agnostic: 使用者不用理会资料怎麽来。
  5. Continuous session awareness: 当client中断连线之後,可以重新连线并且讯息不会消失。

虽然起出被设计用於 IoT (Internet of Thing) 装置,但目前MQ被广泛运用在Platform因此在2019 年时MQTT正式提出v5版本更被推荐,主要就是为了platform 平台新的需求新增加功能。(目前市面上有两个版本,v3.1.1、v.5) MQTT Architecture

MQTT Architecture

From personal blog

MQTT v3.1.1 Features

在功能面MQTT 是以 v3.1.1作为基础的功能,而v5则是为云服务进行扩充但也更改一些特性,如QoS...。MQTT与传统意义有些许不一样。如下比较表:

MQTT TraditionalMQ
Persistent Message 当consumer 取的讯息之前,可设定将讯息保存在MQ中,直到被取用 当consumer 取的讯息之前,可设定将讯息保存在MQ中,直到被取用
Distribution Ability 透过Topic的方式可很轻松的进行传递给多个consumer 传统的consumer与queue是一对一的绑定,不太能分享讯息
Queue Name 使用上完全不用理会name 是否冲突的问题,只要在乎想订阅的Topic 须自行管理queue 的name

MQTT v3.1.1主要功能有QoS、Topic、Persistent Session(重新连线後Topic还存在)、Retained Messages、Last Will。

1. Qos(Quality of Service):

代表的是发送与接收讯息的品质,可设定0-2这个区间。

  • At most once (0): Producer 就是单纯发送之後不用确认是否broker有收到;Broker 发送至consumer也不会确认是否收到。

  • At least once (1): Producer 就是单纯发送之後会等待 PUBACK 封包确认有收到;同理Broker 发送至consumer也需等待PUBACK

  • Exactly once (2): Producer 每发送讯息之後就会进行3向交握,确认是否有收到,并保证只收到一次;同理consumer 接收broker 讯息也是如此。

2. Topic

MQTT Topic是由utf-8 编码组成,如Http的URL的概念,透过"/"进行分阶层。如下图,myhome阶层下groundfloor、livingroom、temperature等,如同REST 架构中对於URI的规范类似。

2.1 Topic 特殊符号:

  • ”#”: 代表的垂直的概念,指的是该阶层以下的全部Topic都订阅, ex: myhome/groundfloor/#,表示订阅myhome/groundfloor/kitchen、myhome/groundfloor/livingroom、myhome/groundfloor/livingroom/..的意思。

  • ”+”: 代表水平的概念,使用该符号的阶层所处的阶层可以替换成任何字元。ex: 以myhome/groundfloor/+/temperature为例,”+”可替换成kitchen、livingroom 的概念。 代表同时订阅: myhome/groundfloor/kitchen/temperature、myhome/groundfloor/livingroom/temperature等Topic。

  • ”$”: 以此关键字为首的并不支援订阅的,该关键字是MQTT用於输出内部状态的保留字。ex: $SYS/broker/clients/connected,可取得有多少装置连线。

3. Persistent Session:

当clinet 对MQTT 连线断掉时,Topic 将会自动的discard。但为了解决这个问题,Persistent Serssion的设计就是为了解决这个问题而生。

有效时broker 存取的东西:

  • Existence of a session (even if there are no subscriptions).
  • 所有的subscription 。
  • QoS 尚未完成传输的message。
  • QoS 1、2 尚未传给Client的message都会留存。
  • 所有QoS 2 未完成Ack的message 。

Persistent Session使用方式
就是在连线的时候需要将option的clean session 设定为false。

4. Retained Messages:

主要是在producer上的功能,发送讯息後会将讯息保持在Topic 上,使的新的加入者也可以获取最新的息。若在没有设定的情况下,新加入的consumer不会收到上一个以发送过的讯息。

5. Last Will and Testament(lwt)

是在producer上的功能,当Producer断线的时候,可指定lwt的Topic,与想要传送的讯息。这功能主要用来debug用的,官方提供这种功能很适合放在上online and offline 的管理上。

MQTT v5 features and v 3.1.1 features comparison

在这个版本中整体使用方式,MQTT v5与v3.1.1之间功能上的的差别在於 QoS 1 以上不再重传讯息、retained messages、persistent sessions不再支援了。

  1. MQTT QoS v5 、v3.1.1 之间的定义是一样的,但v5 的版本不在TCP 连线健康的情况下重传讯息。 原先的v3.1.1 版本若在一段时间内没收到 ack 将会在retry,这可能造成因为效能问题导致未回传的装置loading 更重。
  2. retained messages: v5中Message Expiry Interval用来取代此功能,可以将其设定一个时间後并删除。
  3. persistent sessions: 在v3.1.1中若中途有producer将clean session设定为true时,之前所存的message将会被一起被删除,v5 中Session Expiry Interval 进来取代此功能。

MQTT v5 User Properties

类似http header 的概念,可以在每一个讯息上加入一个property header ,consumer 端可依赖该栏位进行运用。Broker 根据consumer 所订阅的设定进行讯息routing。

MQTT v5 Shared Subscriptions

在v5的版本中,原生支援load balance的功能,consumer 可在建立连线的时候设定Broker shared选项绑定多个consumer 成为一个群组。

MQTT v3.1.1 v.s MQTT v5能力比较

在Intel i7 9750H、16GB RAM在Docker 环境下测试,其中使用 eclipse-mosquitto:2.0.11 Image 作为MQTT broker。由於MQTT v5的版本在Open Source 社群上并未完整支援,以Eclipse MQTT 社群为例,目前完整支援MQTT v5的只有Java、Python、C/C++等三种。

但实际使用Java、Python 发现并未完全支援,只有C语言有完整支援,如下图所示。因此在实验的部份采用Mosquitto 所提供的mosquitto_pub 作为Publisher;使用npm 平台的mqtt v4.2.6版本作为Subscriber进行实做。由於Nodejs该模组在publish 的部份,会因Nodejs中的Event 排程受到影响,因此只使用Subscriber 功能。

实验分为两种测试,吞吐量测试(TPS)、精准度测试(QoS)吞吐量测试分为Publisher与Subscriber 两种角色,在_Publisher 的配置以1、3、5、7、10 个Publisher 进行测试;Subscriber 同 Publisher ,分成1、3、5、7、10 个 Subscriber的场景配置,将发送100万个封包计算平均每秒的吞吐量精准度测试的部份配置分成1、3、5、7、10 个 Subscriber_与1个 Publisher进行测试,将发送100万个讯息,平均计算每个Subscriber收到的数量

  • 吞吐量测试(TPS): TPS = Requests/Per Second
  • 精准度测试(Qos) Precision= sum(Correct Request)/Requests

测试1- [1, 3, 5, 7 ,10 ] publisher + 1 subscriber

当Publisher 增加时,Publisher TPS 明显的下降,但Subscriber TPS 则线性成整且QoS不变,代表着mosquitto不会因为封包数量变大,造成不一样的Qos。换句话说Client (Publisher) 之间并不会互相影响Subscriber所收集到的资讯。

测试2- 1 publisher + [1, 3, 5, 7 ,10 ] subscriber

当Subscriber 增加时,Publisher TPS 并没有什麽改变,且Subscriber TPS、QoS也不变,代表着mosquitto不会因为封包数量变大,造成不一样的Qos。换句话说Client (Subscriber)之间并不会互相影响。

测试3- 1 publisher + 1 subscriber,以一次1000、10,000、40,000、70,000、100,000 送出讯息,达1,000,000 条讯息後,纪录TPS、QoS取平均值。

在Publisher当一次传输的封包变少时,TPS、QoS 会以指数的方式成长。一次的数量超过极限的吞吐量,则会造成Subscriber QoS下降,因为mosquitto 预设机制为当QoS > 0时,broker内部给单一个Client的内存queue封包数量为1000条讯息。因此只要超过一定的吞吐量会造成QoS降低。同时讯息数量大,会造成壅塞的情形,使Publisher、Subscriber 的 TPS 受到影响。

Subscriber 与 Publisher 都以QoS 为2的状态下尽情测试,mosquitto 以预设值进行量测。发现MQTT v3.11、v5 并未有明显差异,且v5的效能些微比v3来的弱一点。且透过上述实验可得到以下几点结论:

  1. 使用MQTT时,未必将QoS调整到越高越好,由於当QoS > 0时 Broker将会限制client缓存Queue,就有可能发生Publisher 送出的资料被Broker舍弃的问题,以致实际QoS降低。
  2. MQTT Broker并不这麽适合用来当Micro Service中的Broker,由於无法正确预期资料的传输,有可能因此导致重要的错误。
  3. 在大部分情况建议MQTT的QoS设置为0会更好,由於MQTT本基於TCP,因此保证其一定会送至或传输到目的地。然而若 QoS > 0则会因为一些确认机制导致变慢,使得TPS、QoS 不如预期。

结论

MQTT v3.1.1、 v5效能并未有大的差异,且v5的版本提供更多的功能。虽然官方文件上所述QoS的实作方面有受到调整,但经过测试後并未有大的差异,但市场上的所提供的工具目前很少,相信未来MQTT v5的版本是比v3.1.1来的更好更实用的。

参考资料

MQTT 文章
MQTT Client 工具


<<:  qt中实现配置文件

>>:  在 ubuntu 21.04 上轻松安装呒虾米

【设计+切版30天实作】|Day25 - Carousel区块 - 把Carousel Caption和Indicators改成心目中理想的模样

前面完成了「Steps」区块,今天来完成「Carousel」的区块。 数据收集 margin-to...

[Day 11] 多对多关联的变形:Parent-Child reference

之前我们看过了透过 DAO 方式,来处理资料之间呈现一对多关联,或者多对多关联的做法。 今天我们来看...

Day12:终於要进去新手村了-Javascript-资料型态转换-将字串变成数字

前两篇文章中有认识到了变数是要用来放资料的,但是有时候会遇到资料内容需要不同的类型,比如说数字,它可...

[Day23]ISO 27001 附录 A.11 实体及环境安全

这个章节的重点在於资讯管理系统的实体环境的保护。 不是这种保护 XD 不过,比较常跟受稽方讨论到乖乖...

Gulp 基础介绍 gulp-sass DAY80

今天要来介绍 gulp-sass 如何安装与使用 gulp-sass 介绍 https://www....