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

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

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

时间: 2024-11-25 14:55:53

Mosquito的优化——订阅树优化(八)的相关文章

[Poi2010]Monotonicity 2 (线段树优化DP)

题目描述 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度为L的子序列(不要求连续),要求这个子序列的第i项和第i+1项的的大小关系为s[(i-1)mod K+1].求出L的最大值. 输入 第一行两个正整数,分别表示N和K (N, K <= 500,000).第二行给出N个正整数,第i个正整数表示a[i] (a[i] <= 10^6).第三行给出K个空格隔开关系符号(>.<或=),第i个表示s[i]. 输出 一个正整数,表示L的

HDU4719-Oh My Holy FFF(DP线段树优化)

Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 606    Accepted Submission(s): 141 Problem Description N soldiers from the famous "*FFF* army" is standing in a line, from le

hdu 4719 Oh My Holy FFF(dp线段树优化)

Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 848    Accepted Submission(s): 219 Problem Description N soldiers from the famous "*FFF* army" is standing in a line, from le

题解 HDU 3698 Let the light guide us Dp + 线段树优化

http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 62768/32768 K (Java/Others) Total Submission(s): 759    Accepted Submission(s): 253 Problem Description Plain of despair was

项目优化经验分享(八)TeamLeader经验总结

引言 通过前面的七篇博客,我把自己在项目优化过程的经验进行了分享,今天这篇博客,作为一个总结,就来讲讲作为一个TeamLeader,在项目管理中遇到的问题和解决经验! 正文 问题一:团队之间怎么沟通? 一个好的开发团队,首先要营造一个好的开发环境,团队之间要有良好的沟通互动,有时候在开发一期项目的时候需求还不是很明确,需要边做边确定,而这时就需要团队之间频繁积极的进行沟通,初步模型要积极进行评估讨论,不然就会出现辛苦几天而来的产品不符合需求,打回去重做.这不仅影响开发人员的心情,更重要的是影响开

Write Optimized B-Trees:优化B树索引的写性能

本文主要是笔者作报告的PPT,主要讲解优化B树索引的写性能(同时尽可能不损失读性能),PPT并不长,相信能使人较快领会这篇论文的思想.

BZOJ 1835 基站选址(线段树优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1835 题意:有N个村庄坐落在一条直线上,第 i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村 庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了.如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi.现在的问题是,选择基站的位 置,使得总费用最小. 思路: 另外,程序中的n=n+1,m=

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 线段树优化建图+费用流

题目描述 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元.作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢? 输入 第一行包含一个正整数n(1<=n<=5000),表示强盗的个数. 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]

【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp

题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a variant of the game for themselves to play. Being played by clumsy animals weighing nearly a ton, Cow Hopscotch almost always ends in disaster, but this has