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

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程序不支持通配符“+”,但是支持通配符“#”。

Mosquito的优化——订阅树优化(八)相关推荐

  1. mosquito源码分析和优化

    源码分析 Mosquito的优化--epoll优化(七) Mosquito的优化--订阅树优化(八) Mosquito的优化--其他优化(九) 其它问题

  2. 网站SEO优化只需做到八个方面

    网站SEO优化包括站内优化和站外推广,不管哪种都是可以大幅提高公司的曝光度,并吸引用户浏览站内内容,来达成交易的.下面咱们就来讲讲网站SEO优化中的站内优化. 1.网站结构 分析网站结构是否合理,搜索 ...

  3. CF786B Legacy(线段树优化建边模板 + 最短路)

    整理的算法模板合集: ACM模板 目录 线段树优化建边 题目传送门 由于本题的数据达到了1e5,所以如果直接全部暴力连边的话会达到O(n2)O(n^2)O(n2),时间包括内存都受不了.因此我们需要使 ...

  4. P1047 校门外的树(线段树优化)(校门三部曲)难度⭐⭐

    校门三部曲,总算完结了!完结散花! 难度呈阶梯状,都可以用线段树解决. 第一部 P1047 校门外的树(线段树优化)难度⭐⭐ 第二部 P1276 校门外的树(增强版)(线段树)校门三部曲难度⭐⭐⭐ 第 ...

  5. SEO站内优化系列讲座(八)——

    SEO站内优化系列讲座(八)-- 一.面包屑路径 合理的颜色有利于用户点击: 现在的位置:首页的目标关键词 > 分集剧情介绍 > 新拿什么拯救你我的爱人电视剧(对) 现在的位置:放网站的名 ...

  6. string [线段树优化桶排]

    题意大概是给你一个字符串,1e5次修改,每次给一个区间升序排列或降序排列,最后输出这个字符串; 其实是个挺裸的线段树优化题;但是我没有意识去结合桶排,扑该..... 首先 1.40分算法 O(NMlo ...

  7. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  8. 记一次接口性能优化实践总结:优化接口性能的八个建议

    前言 最近对外接口偶现504超时问题,原因是代码执行时间过长,超过nginx配置的15秒,然后真枪实弹搞了一次接口性能优化.在这里结合优化过程,总结了接口优化的八个要点,希望对大家有帮助呀~ 数据量比 ...

  9. hdu 4521(线段树优化dp)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Pro ...

最新文章

  1. SpringBoot b2b2c 多用户商城系统 ssm b2b2c
  2. 使用Python实现真正意义上的随机数,谁能破解奖励1千万
  3. Android实用代码(不定期更新)
  4. Git复习(九)之理解git工作区和暂存区
  5. C#中的深复制与浅复制
  6. ckeditor 图片上传_关于上传中国鸟类图库和哺乳动物图库物种数量及称号的最新规定...
  7. IOS 高级语法与设计模式5(5.3 协议的基本概念及用法)
  8. cocos2d-iphone源码分析(2):Director
  9. 用Java简便地去重+排序(洛谷P1059题题解,Java语言描述)
  10. API 安全最佳实践,不要等出事后“捶胸顿足”
  11. IDEA如何执行maven命令进行打包编译及常用命令
  12. TypeError: can‘t convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory fi
  13. 通过创建一条链来学习区块链 (1)
  14. 四种大数据分析方法 ,大数据学习入门必须掌握!
  15. 基于Docker swarm 集群搭建SSR 学习
  16. cad 2019 mac安装破解详细图文教程
  17. [深度学习] 深度可分离卷积
  18. 怎样才可以关掉Mac电脑开机启动项?
  19. 记录一下我的phpcms下载模板的下载列表页面不能够显示出列表页面
  20. 【NOIP2009PJ】细胞分裂

热门文章

  1. MATLAB_排列组合_组合生成程序
  2. C++接收字符串数组_电脑编程 你该知道的字符知识 C语言程序设计字符数组全归纳...
  3. Go 标准库 http.FileServer 实现静态文件服务
  4. 初学Java,LinkedList功能最全的集合类
  5. 小程序点击显示隐藏(点击标题,内容显示,再次点击隐藏,同时切换箭头的状态,且默认第一组的内容显示)
  6. php mysql 链表_浅谈PHP链表数据结构(单链表)
  7. 网页数据分页显示php,PHP网页设计例子:用PHP3完成MySQL数据的分页显示
  8. rsa算法python_GitHub 热门:Python 算法大全,Star 超过 2 万
  9. mysql盲注绕过_盲注 绕过技巧
  10. iphone屏幕录制_iphone投屏到电脑详细教程