基于MQTT协议的Mosquitto数据订阅机制优化与性能分析

2021-11-22 08:13田志刚职如昕
物联网技术 2021年11期
关键词:子树代理服务器哈希

黄 迪,徐 湛,田志刚,职如昕

(1.北京信息科技大学 信息与通信工程学院,北京 100101;2.北京信息科技大学 现代测控技术教育部重点实验室,北京 100101;3.清华大学,北京 100084)

0 引 言

物联网(IoT)是通信技术与互联网技术结合的新产物,它使得越来越多的设备不断接入网络,并产生大量的数据。特别是在2021年,物联网收集的数据和设备的接入量预计将比2020年翻一番。海量数据接入对数据实时响应的要求越来越高,传统的设备、技术和应用服务已经不能满足物联网的深度发展。缩短接收数据的响应时间、实现数据实时处理以及提高并发设备接入数量等成为物联网研究面临的新挑战。

在消息代理服务器研究方面,多数研究者主要集中在对消息代理服务器的应用上,使用MQTT协议基于发布/订阅的架构模式来传输数据包,并且取得了一定的成果[1-6]。例如文献[7]结合Redis和Mosquitto,设计完成了以MQTT为传输协议的传递信息服务器,具体功能是针对用户订阅的数据消息实现推送,并具备验证接入用户身份、进行安全权限检查、话题的自动订阅、统计热点话题、监控服务器运行状态等功能。文献[8]开发了基于MQTT协议的电力设备温度在线监测系统。

从上述文献中可以看出,研究者主要利用消息代理服务器作为中间媒介,结合不同软件实现在不同场景下的数据传输功能。例如即时通信系统、消息推送系统、多设备监控系统以及智能手表等。主要的目标在于功能的实现,而对于中间消息代理服务器的选择、整体性能的优劣以及适用场景、文件传输方法等未有较多的阐述。

在现有的改进方法中,文献[9]中提出了一种适用于大文件传输的传输方式,其方法是将消息作为主体,产生一份拷贝由每个订阅者进行共享,然后进行统一发送,从而降低内存空间的占用。文献[10]对Mosquitto内部的订阅树机制进行了一定的优化,提出了一种改进方法。该方法利用键树多重链表表示法中的分支节点思想,实践于订阅树结构中,并且利用哈希表来管理订阅主题和订阅者。该方法在性能上有所改善,减小了Mosquitto服务器在不同消息发布数量情况下的时延。虽然上述研究在内部机制和传输方式上有一定的改善,但缺少对消息订阅匹配选择方式以及消息代理服务器查找接收数据的响应时间、设备接入并发量的测试情况的研究[11-13]。

本文研究的对象是代理服务器的内部订阅匹配机制,对支持MQTT协议数据收发的主流服务器Mosquitto的内部机制进行优化,综合运用订阅树和哈希表进行信息订阅的管理,即利用订阅树管理字符数据信息订阅,利用哈希表管理JSON格式等文件的精确主题信息订阅。通过将订阅方式分类并按照合适的结构进行匹配,减小消息代理服务器查找接收数据的响应时间,提升消息代理服务器并发接入设备数量的性能[14-15]。

1 订阅树机制流程与分析优化

1.1 订阅树的内部构成和构建方法

在Mosquitto内部,topic(主题)和客户端的所有关系全部由订阅树管理。在订阅树中,topic被拆解、分割,然后使用树状结构将分割后的片段相连。订阅树整体结构如图1所示,其结构主要表现在以下两个方面。

树节点的含义:在树的每个节点中,topic的分级片段都包含在内部,每个划分的片段对应订阅树的一个节点。对于每个节点的topic,其组成结构是:根节点至该节点整体的节点数,节点分支的指向是该节点对应的订阅者列表。如图1所示,圆形结点表示主题片段,矩形列表示订阅者。树的存储方式:订阅树中采用文献[16]中的“左孩子右兄弟”方法来构建,根据树结构的相对位置,保存了topic相互之间结构的相对关系。

图1 订阅树结构

树结构的划分:在Mosquitto内,业务子树和系统子树组成订阅树的两个部分。其中根结点的左孩子为业务子树的根节点;根节点的右兄弟为系统子树的根结点。订阅者与被订阅主题之间的联系,由业务子树负责,以确保消息转发业务在服务器内正常运行;而系统子树负责的是:管理当前服务器的运行时间、客户端连接数量、消息转发总数、内存占比等系统信息。通常情况下,消息订阅者都存在于业务子树的节点上。因为所有的客户端由业务子树管理,它确保服务器能够完成消息转发与推送工作;而系统子树所面对的是系统管理者,它帮助系统管理者了解当前服务器的运行情况,以便做下一步的决策。

1.2 订阅匹配流程和不足的分析

对订阅树按照topic搭建后,主题被分割成多部分并储存在树中。从树的根节点开始到任意节点所经过的轨迹路径为其中一条主题的订阅规则,每个节点都在管理各自所对应的列表。此列表保存着客户端的数目和订阅者的具体信息。因此,订阅树的形状由订阅主题的数量和分级直接决定并受其影响,这种影响是至关重要的,也会进一步影响操作效率。在Mosquitto中,查询、插入和删除是订阅树的基本操作,而这些操作均会用到对订阅树的遍历[17-18]。

以插入操作为例,首先比较订阅主题的每个分级内容与订阅树的各层节点,依次搜寻能对应的节点。如果能寻找到,则继续下一级匹配,一直进行到订阅的主题全部完成匹配,然后将订阅内容连接到对应节点的订阅列表中。在匹配过程中若出现内容分级匹配无法成功,则说明订阅树目前还没有所需主题。需要将不匹配的节点添加至订阅树中,并将所订阅的内容添加到当前已生成节点的订阅列表里。

图2为订阅树的具体匹配流程。如果订阅主题在列表中的当前分级不为空,且能够与订阅树节点内容相匹配,则进入到下一个分级并继续进行比较。如果订阅主题在列表中的当前分级不为空,且未能与订阅树中当前节点的内容相匹配,则需要为主题的分级新插入一个节点,继续以新增的节点作为子树的根节点进行下一层的匹配。如果订阅主题列表为空,则将其添加至当前节点对应的订阅列表中。

图2 订阅树的匹配流程

对于上文所述订阅树的订阅流程和匹配机制,其优点是提供了比较清晰的逻辑,对开发和维护十分有利;但是,当每一个客户端进行插入、查找和删除操作时,每一个操作对树都要进行遍历。如果不断加大树的深度,特别是在网络状况差时,客户端的频繁重连操作,将导致对订阅树的遍历操作不断增加,产生较大的响应时延,效率较低。

目前的研究主要是使用两种方法优化。第一种是使用前缀树思想在订阅树根节点的下一个节点建立索引,按照关键字符进行快速定位,然后快速查找具体匹配主题信息。另一种是将订阅树存储方式转变为使用带索引哈希表储存,通过主题迅速定位订阅列表,从而实现快速查找和匹配。虽然哈希表从一定程度上减少了订阅树的深度,达到了快速查找和匹配到相应的订阅列表的目的,但是持续增加的订阅主题量导致哈希表长度不断加大,在进行主题匹配订阅时,对主题查找需要进行更多操作,造成效率低下,且不断添加长的列表也增加了哈希冲突,这就对哈希函数的构造方法提出了更严格的要求。

1.3 订阅树机制的优化与实现

针对Mosquitto订阅树的缺陷,并根据物联网实时传输数据的需求,提出将订阅树和哈希表相结合的优化方式。首先将订阅匹配分为精确订阅和字符数据订阅。对于精确的主题内容使用哈希表精确匹配,对于字符数据则使用订阅树进行匹配。这种方式的优势体现在:对于精确匹配的主题,文件所含数据量会较大,需要对数据进行频繁删减和查找;而哈希表查找速度快,时间复杂度几乎为常数,大大降低了数据的存储和查找消耗的时间,因此能够很快定位到具体主题下的订阅列表,提高匹配查找的效率。在具体的哈希函数的算法选取上,可以根据精确匹配的场景灵活进行选取,避免因匹配数量过大导致订阅误差。对于字符数据匹配,利用订阅树结构能有效地减少树的深度,通过对关键字符的判断,确定订阅是单层匹配还是多层匹配,从而在相关主题下接收对应的信息。

具体实现时在源代码的订阅部分加入判断,确定后续订阅匹配流程。使用哈希表时,在源代码中添加合适的哈希函数和哈希表的结构体,如图3所示。相比于只使用订阅树结构,哈希表利用自身特性通过算法函数将关键码值映射到表中的一个位置,订阅者订阅的主题为表中key值,内容则是从根节点到当前节点共同组成的主题;value值为每个主题对应订阅者列表的地址。通过关键码值对表直接进行访问,相比于树结构,可以快速寻找并定位到具体的主题和订阅列表,从而快速进行匹配。哈希表在实际使用中也更容易控制表的长度,有利于存储。除了查找匹配,在执行插入、删除数据操作时也十分便捷,减少对数据操作的时间。

图3 哈希表组成图

2 实验内容和结果分析

实验数据的发布按照MQTT协议消息发布的服务质量QoS=1进行设计。由图4可以看到,在发布者发送数据给代理服务器后,代理服务器会发送一个带有PUBACK(如图4中虚线框所示)的报文信息,从而确定代理服务器收到发布者所发来的报文。

图4 QoS=1时的发布/订阅流程

在表1所列软硬件配置的服务器上搭建客户端和Mosquitto,完成连接和配置。

表1 软硬件配置

在服务器运行正常后,分别对优化前后的Mosquitto进行测试。首先测试发布相同消息时代理服务器与客户端订阅匹配后接收到消息的时间,并增加发送消息的次数和消息量,查看性能变化。

见表2所列结果,通过发送时间戳并抓包测试客户端发布消息后到代理服务器接收消息之间的时间间隔,经过4次测试,每次发送JSON文件的数据量逐渐增大。对比优化前后的响应时间可以看出,修改后的结构可以有效降低查找接收消息的响应时间,平均降幅约为24%。

表2 测试运行结果对比

对服务器进行并发数测试,利用压测工具进行4次测试,在5 min内均持续发送1万条消息。测试结果如图5所示,并发接入数在优化后明显好于优化前,平均增幅约为10%。

图5 代理服务器并发接入数性能图

本文针对所提的方法进行了压力测试。压测时CPU占用率的结果如图6所示,虽然优化后订阅机制的复杂度相较于优化前有所增加,但增加的复杂度均能控制在合理水平区间,不影响服务稳定运行。

图6 代理服务器CPU占用率

3 结 语

本文研究了消息代理服务器Mosquitto订阅树机制,分析了订阅树机制存在的缺陷,提出了基于订阅树和哈希表结合的优化方法,在此基础上进行了测试验证。测试结果表明,优化方法可以有效降低消息代理服务器的响应时间,提升设备接入并发数量,使得消息代理服务器可以用更小耗时接收更多设备发送的数据,有利于减小服务器使用数量,使其高效稳定运行。下一步的工作将继续深入研究不同应用场景下的优化方法,并降低实现复杂度。

猜你喜欢
子树代理服务器哈希
一种新的快速挖掘频繁子树算法
广义书本图的BC-子树计数及渐近密度特性分析*
书本图的BC-子树计数及渐进密度特性分析∗
地铁信号系统中代理服务器的设计与实现
IP地址隐藏器
基于覆盖模式的频繁子树挖掘方法
基于维度分解的哈希多维快速流分类算法
基于同态哈希函数的云数据完整性验证算法
一种基于Bigram二级哈希的中文索引结构
一种容侵系统的设计