Mosquito的优化——订阅树优化(八)

117 篇文章 6 订阅
25 篇文章 113 订阅

本文由逍遥子撰写,转发请标注原址:

http://blog.csdn.net/houjixin/article/details/46413783


http://houjixin.blog.163.com/blog/static/35628410201558423159/

8.1  mosquitto的订阅树机制

在mosquitto原始版本中,所有的订阅关系都是通过一颗订阅树来维护,在订阅树中,topic将被按照“/”组织成树状结构,如图5-3所示的订阅树,其中订阅树的每个节点都是一个topic分级,每个节点对应的topic就是从根节点到当前节点所组成的topic,每个节点旁边的星状列表即是该节点所对应的订阅列表。


图8-1 订阅树

在mosquitto原始版本程序中,订阅树按照topic来搭建,topic的数量和分级形式直接决定了订阅树的形状,进而影响操作效率。在mosquitto中,对上述订阅树的操作主要是查询、插入和删除操作,上述操作都涉及对订阅树的遍历。以插入操作为例,将topic各分级的内容与订阅树的各层节点相比较,依此找到相匹配的节点,如果找到,则继续下一级匹配,直到订阅的topic全部匹配成功,此时只需将context挂到订阅树的当前节点的订阅列表中即可;如果匹配过程中有topic分级的内容无法匹配成功,则说明订阅树中尚不存在所订阅的topic,此时需将topic分级中不匹配的节点加入到订阅树中,并将context挂到新生成节点的订阅列表中。例如,如果一个新的客户端context1订阅了topic:a1/b1/c1,则mosquitto内部首先将topic按照“/”分割为a1、b1、c1三级列表,然后以递归方式将topic列表中的内容与订阅树中各节点的内容进行匹配;具体匹配过程为:

如果topic列表中当前分级的内容不为空,且与订阅树中节点的内容相匹配的,则继续选择topic列表中的下一个分级内容,与订阅树中当前节点的子树进行同样的匹配;

如果topic列表中当前分级内容不为空,且订阅树的当前层中没有找到与分级内容想匹配的节点,则为topic的该分级新增一个节点;继续以该新增节点为子树的根节点进行匹配。

如果topic列表为空,则将其挂到对应订阅树的当前节点对应的订阅列表中;

图8-2即为上述匹配过程的流程图。


图8-2 订阅树的匹配流程

8.2、  订阅机制的优化

Mosquitto的原来对订阅着的组织采用树形结构,这种方式的优点是在逻辑上比较清晰,但是其插入、查找和删除的效率较低。

针对mosquitto订阅树的这种缺陷,本次优化过程将去掉订阅树,采用hash表的方式存储各topic及其订阅列表。hash表的方式主要是为了通过topic快速定位到其订阅列表,因此,hash表的value是每个订阅列表的地址,key是该订阅列表所对应的topic,其内容是从根节点到当前节点的topic内容所组成,以图5-3所示的hash表为例,节点c1对应的hash表项的key是:a1/b1/c1,value及时Lc1,针对图5-3中所示的订阅树,其产生的订阅hash表如图5-5所示:


8-3订阅hash表

8.3、 优化方法

订阅机制的优化主要集中在文件subs.c中,具体则涉及以下接口函数:

mqtt3_retain_queue

mqtt3_subs_clean_session

mqtt3_db_messages_queue

mqtt3_sub_remove

mqtt3_sub_add

在mqtt3_sub_add函数中主要完成mosquitto的订阅操作,将首先搜索hash表中是否存在该context所订阅的topic,如果存在,则将其挂到对应的订阅列表中即可,否则创建一个新的hash结构体,在该结构体中保存此topic,并将context挂到该topic的订阅列表中。

函数mqtt3_db_messages_queue中主要完成mosquitto的消息发布操作,在该函数中将对topic进行拆分检查各种以“#”结尾的子topic是否存在于订阅hash表中,如果存在则进行消息发送。例如某一context欲向主题:a1/b1/c1发布消息,则需要在函数mqtt3_db_messages_queue中检查以下几种topic是否存在于订阅hash表中:

a1/#

a1/b1/#

a1/b1/c1/#

a1/b1/c1/

如果主题有存在于hash表中,则将消息挂载到对应topic订阅列表的各个context的消息队列中。

函数mqtt3_sub_remove和mqtt3_subs_clean_session主要完成在hash表中清除context的操作,该操作需要事先保存context所订阅的topic,此时只需查找其所订阅的topic是否存在于订阅hash表中即可,如果存在,则再从订阅列表中删除该context,否则直接返回。

函数mqtt3_retain_queue完成对某个context的消息队列的保存操作,它同样不需要遍历订阅树,只需要根据其操作的context中取出所订阅的topic,然后再通过该topic从订阅hash表中找到对应的context即可调用_retain_process函数直接完成操作。

优化后的mosquitto程序不支持通配符“+”,但是支持通配符“#”。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
针对mosquitto消息发送机制中需要全扫描所有context造成的低效问题,进行了一次优化。该优化增加了一个hash表,用于保存所有带消息的context。在消息发送时,只需要扫描这个hash表中的context,而不需要扫描全部的context,从而提升系统的运行效率。具体操作是将带消息的context存储在hash表中,在发送消息时只对这个hash表进行扫描,以确定哪些context有消息需要发送。这样可以减少不必要的扫描操作,提高系统的性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Mosquito优化——其他优化(九)](https://blog.csdn.net/hjx_1000/article/details/46413941)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [mosquitto-1.4.11-add:只增加新功能,,未做性能优化,最小程度修改原始文件;附加功能可通过配置文件打开...](https://download.csdn.net/download/weixin_42107374/16070072)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值