黃 迪,徐 湛,田志剛,職如昕
(1.北京信息科技大學(xué) 信息與通信工程學(xué)院,北京 100101;2.北京信息科技大學(xué) 現(xiàn)代測(cè)控技術(shù)教育部重點(diǎn)實(shí)驗(yàn)室,北京 100101;3.清華大學(xué),北京 100084)
物聯(lián)網(wǎng)(IoT)是通信技術(shù)與互聯(lián)網(wǎng)技術(shù)結(jié)合的新產(chǎn)物,它使得越來(lái)越多的設(shè)備不斷接入網(wǎng)絡(luò),并產(chǎn)生大量的數(shù)據(jù)。特別是在2021年,物聯(lián)網(wǎng)收集的數(shù)據(jù)和設(shè)備的接入量預(yù)計(jì)將比2020年翻一番。海量數(shù)據(jù)接入對(duì)數(shù)據(jù)實(shí)時(shí)響應(yīng)的要求越來(lái)越高,傳統(tǒng)的設(shè)備、技術(shù)和應(yīng)用服務(wù)已經(jīng)不能滿足物聯(lián)網(wǎng)的深度發(fā)展??s短接收數(shù)據(jù)的響應(yīng)時(shí)間、實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)處理以及提高并發(fā)設(shè)備接入數(shù)量等成為物聯(lián)網(wǎng)研究面臨的新挑戰(zhàn)。
在消息代理服務(wù)器研究方面,多數(shù)研究者主要集中在對(duì)消息代理服務(wù)器的應(yīng)用上,使用MQTT協(xié)議基于發(fā)布/訂閱的架構(gòu)模式來(lái)傳輸數(shù)據(jù)包,并且取得了一定的成果[1-6]。例如文獻(xiàn)[7]結(jié)合Redis和Mosquitto,設(shè)計(jì)完成了以MQTT為傳輸協(xié)議的傳遞信息服務(wù)器,具體功能是針對(duì)用戶訂閱的數(shù)據(jù)消息實(shí)現(xiàn)推送,并具備驗(yàn)證接入用戶身份、進(jìn)行安全權(quán)限檢查、話題的自動(dòng)訂閱、統(tǒng)計(jì)熱點(diǎn)話題、監(jiān)控服務(wù)器運(yùn)行狀態(tài)等功能。文獻(xiàn)[8]開(kāi)發(fā)了基于MQTT協(xié)議的電力設(shè)備溫度在線監(jiān)測(cè)系統(tǒng)。
從上述文獻(xiàn)中可以看出,研究者主要利用消息代理服務(wù)器作為中間媒介,結(jié)合不同軟件實(shí)現(xiàn)在不同場(chǎng)景下的數(shù)據(jù)傳輸功能。例如即時(shí)通信系統(tǒng)、消息推送系統(tǒng)、多設(shè)備監(jiān)控系統(tǒng)以及智能手表等。主要的目標(biāo)在于功能的實(shí)現(xiàn),而對(duì)于中間消息代理服務(wù)器的選擇、整體性能的優(yōu)劣以及適用場(chǎng)景、文件傳輸方法等未有較多的闡述。
在現(xiàn)有的改進(jìn)方法中,文獻(xiàn)[9]中提出了一種適用于大文件傳輸?shù)膫鬏敺绞?,其方法是將消息作為主體,產(chǎn)生一份拷貝由每個(gè)訂閱者進(jìn)行共享,然后進(jìn)行統(tǒng)一發(fā)送,從而降低內(nèi)存空間的占用。文獻(xiàn)[10]對(duì)Mosquitto內(nèi)部的訂閱樹(shù)機(jī)制進(jìn)行了一定的優(yōu)化,提出了一種改進(jìn)方法。該方法利用鍵樹(shù)多重鏈表表示法中的分支節(jié)點(diǎn)思想,實(shí)踐于訂閱樹(shù)結(jié)構(gòu)中,并且利用哈希表來(lái)管理訂閱主題和訂閱者。該方法在性能上有所改善,減小了Mosquitto服務(wù)器在不同消息發(fā)布數(shù)量情況下的時(shí)延。雖然上述研究在內(nèi)部機(jī)制和傳輸方式上有一定的改善,但缺少對(duì)消息訂閱匹配選擇方式以及消息代理服務(wù)器查找接收數(shù)據(jù)的響應(yīng)時(shí)間、設(shè)備接入并發(fā)量的測(cè)試情況的研究[11-13]。
本文研究的對(duì)象是代理服務(wù)器的內(nèi)部訂閱匹配機(jī)制,對(duì)支持MQTT協(xié)議數(shù)據(jù)收發(fā)的主流服務(wù)器Mosquitto的內(nèi)部機(jī)制進(jìn)行優(yōu)化,綜合運(yùn)用訂閱樹(shù)和哈希表進(jìn)行信息訂閱的管理,即利用訂閱樹(shù)管理字符數(shù)據(jù)信息訂閱,利用哈希表管理JSON格式等文件的精確主題信息訂閱。通過(guò)將訂閱方式分類并按照合適的結(jié)構(gòu)進(jìn)行匹配,減小消息代理服務(wù)器查找接收數(shù)據(jù)的響應(yīng)時(shí)間,提升消息代理服務(wù)器并發(fā)接入設(shè)備數(shù)量的性能[14-15]。
在Mosquitto內(nèi)部,topic(主題)和客戶端的所有關(guān)系全部由訂閱樹(shù)管理。在訂閱樹(shù)中,topic被拆解、分割,然后使用樹(shù)狀結(jié)構(gòu)將分割后的片段相連。訂閱樹(shù)整體結(jié)構(gòu)如圖1所示,其結(jié)構(gòu)主要表現(xiàn)在以下兩個(gè)方面。
樹(shù)節(jié)點(diǎn)的含義:在樹(shù)的每個(gè)節(jié)點(diǎn)中,topic的分級(jí)片段都包含在內(nèi)部,每個(gè)劃分的片段對(duì)應(yīng)訂閱樹(shù)的一個(gè)節(jié)點(diǎn)。對(duì)于每個(gè)節(jié)點(diǎn)的topic,其組成結(jié)構(gòu)是:根節(jié)點(diǎn)至該節(jié)點(diǎn)整體的節(jié)點(diǎn)數(shù),節(jié)點(diǎn)分支的指向是該節(jié)點(diǎn)對(duì)應(yīng)的訂閱者列表。如圖1所示,圓形結(jié)點(diǎn)表示主題片段,矩形列表示訂閱者。樹(shù)的存儲(chǔ)方式:訂閱樹(shù)中采用文獻(xiàn)[16]中的“左孩子右兄弟”方法來(lái)構(gòu)建,根據(jù)樹(shù)結(jié)構(gòu)的相對(duì)位置,保存了topic相互之間結(jié)構(gòu)的相對(duì)關(guān)系。
圖1 訂閱樹(shù)結(jié)構(gòu)
樹(shù)結(jié)構(gòu)的劃分:在Mosquitto內(nèi),業(yè)務(wù)子樹(shù)和系統(tǒng)子樹(shù)組成訂閱樹(shù)的兩個(gè)部分。其中根結(jié)點(diǎn)的左孩子為業(yè)務(wù)子樹(shù)的根節(jié)點(diǎn);根節(jié)點(diǎn)的右兄弟為系統(tǒng)子樹(shù)的根結(jié)點(diǎn)。訂閱者與被訂閱主題之間的聯(lián)系,由業(yè)務(wù)子樹(shù)負(fù)責(zé),以確保消息轉(zhuǎn)發(fā)業(yè)務(wù)在服務(wù)器內(nèi)正常運(yùn)行;而系統(tǒng)子樹(shù)負(fù)責(zé)的是:管理當(dāng)前服務(wù)器的運(yùn)行時(shí)間、客戶端連接數(shù)量、消息轉(zhuǎn)發(fā)總數(shù)、內(nèi)存占比等系統(tǒng)信息。通常情況下,消息訂閱者都存在于業(yè)務(wù)子樹(shù)的節(jié)點(diǎn)上。因?yàn)樗械目蛻舳擞蓸I(yè)務(wù)子樹(shù)管理,它確保服務(wù)器能夠完成消息轉(zhuǎn)發(fā)與推送工作;而系統(tǒng)子樹(shù)所面對(duì)的是系統(tǒng)管理者,它幫助系統(tǒng)管理者了解當(dāng)前服務(wù)器的運(yùn)行情況,以便做下一步的決策。
對(duì)訂閱樹(shù)按照topic搭建后,主題被分割成多部分并儲(chǔ)存在樹(shù)中。從樹(shù)的根節(jié)點(diǎn)開(kāi)始到任意節(jié)點(diǎn)所經(jīng)過(guò)的軌跡路徑為其中一條主題的訂閱規(guī)則,每個(gè)節(jié)點(diǎn)都在管理各自所對(duì)應(yīng)的列表。此列表保存著客戶端的數(shù)目和訂閱者的具體信息。因此,訂閱樹(shù)的形狀由訂閱主題的數(shù)量和分級(jí)直接決定并受其影響,這種影響是至關(guān)重要的,也會(huì)進(jìn)一步影響操作效率。在Mosquitto中,查詢、插入和刪除是訂閱樹(shù)的基本操作,而這些操作均會(huì)用到對(duì)訂閱樹(shù)的遍歷[17-18]。
以插入操作為例,首先比較訂閱主題的每個(gè)分級(jí)內(nèi)容與訂閱樹(shù)的各層節(jié)點(diǎn),依次搜尋能對(duì)應(yīng)的節(jié)點(diǎn)。如果能尋找到,則繼續(xù)下一級(jí)匹配,一直進(jìn)行到訂閱的主題全部完成匹配,然后將訂閱內(nèi)容連接到對(duì)應(yīng)節(jié)點(diǎn)的訂閱列表中。在匹配過(guò)程中若出現(xiàn)內(nèi)容分級(jí)匹配無(wú)法成功,則說(shuō)明訂閱樹(shù)目前還沒(méi)有所需主題。需要將不匹配的節(jié)點(diǎn)添加至訂閱樹(shù)中,并將所訂閱的內(nèi)容添加到當(dāng)前已生成節(jié)點(diǎn)的訂閱列表里。
圖2為訂閱樹(shù)的具體匹配流程。如果訂閱主題在列表中的當(dāng)前分級(jí)不為空,且能夠與訂閱樹(shù)節(jié)點(diǎn)內(nèi)容相匹配,則進(jìn)入到下一個(gè)分級(jí)并繼續(xù)進(jìn)行比較。如果訂閱主題在列表中的當(dāng)前分級(jí)不為空,且未能與訂閱樹(shù)中當(dāng)前節(jié)點(diǎn)的內(nèi)容相匹配,則需要為主題的分級(jí)新插入一個(gè)節(jié)點(diǎn),繼續(xù)以新增的節(jié)點(diǎn)作為子樹(shù)的根節(jié)點(diǎn)進(jìn)行下一層的匹配。如果訂閱主題列表為空,則將其添加至當(dāng)前節(jié)點(diǎn)對(duì)應(yīng)的訂閱列表中。
圖2 訂閱樹(shù)的匹配流程
對(duì)于上文所述訂閱樹(shù)的訂閱流程和匹配機(jī)制,其優(yōu)點(diǎn)是提供了比較清晰的邏輯,對(duì)開(kāi)發(fā)和維護(hù)十分有利;但是,當(dāng)每一個(gè)客戶端進(jìn)行插入、查找和刪除操作時(shí),每一個(gè)操作對(duì)樹(shù)都要進(jìn)行遍歷。如果不斷加大樹(shù)的深度,特別是在網(wǎng)絡(luò)狀況差時(shí),客戶端的頻繁重連操作,將導(dǎo)致對(duì)訂閱樹(shù)的遍歷操作不斷增加,產(chǎn)生較大的響應(yīng)時(shí)延,效率較低。
目前的研究主要是使用兩種方法優(yōu)化。第一種是使用前綴樹(shù)思想在訂閱樹(shù)根節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)建立索引,按照關(guān)鍵字符進(jìn)行快速定位,然后快速查找具體匹配主題信息。另一種是將訂閱樹(shù)存儲(chǔ)方式轉(zhuǎn)變?yōu)槭褂脦饕1韮?chǔ)存,通過(guò)主題迅速定位訂閱列表,從而實(shí)現(xiàn)快速查找和匹配。雖然哈希表從一定程度上減少了訂閱樹(shù)的深度,達(dá)到了快速查找和匹配到相應(yīng)的訂閱列表的目的,但是持續(xù)增加的訂閱主題量導(dǎo)致哈希表長(zhǎng)度不斷加大,在進(jìn)行主題匹配訂閱時(shí),對(duì)主題查找需要進(jìn)行更多操作,造成效率低下,且不斷添加長(zhǎng)的列表也增加了哈希沖突,這就對(duì)哈希函數(shù)的構(gòu)造方法提出了更嚴(yán)格的要求。
針對(duì)Mosquitto訂閱樹(shù)的缺陷,并根據(jù)物聯(lián)網(wǎng)實(shí)時(shí)傳輸數(shù)據(jù)的需求,提出將訂閱樹(shù)和哈希表相結(jié)合的優(yōu)化方式。首先將訂閱匹配分為精確訂閱和字符數(shù)據(jù)訂閱。對(duì)于精確的主題內(nèi)容使用哈希表精確匹配,對(duì)于字符數(shù)據(jù)則使用訂閱樹(shù)進(jìn)行匹配。這種方式的優(yōu)勢(shì)體現(xiàn)在:對(duì)于精確匹配的主題,文件所含數(shù)據(jù)量會(huì)較大,需要對(duì)數(shù)據(jù)進(jìn)行頻繁刪減和查找;而哈希表查找速度快,時(shí)間復(fù)雜度幾乎為常數(shù),大大降低了數(shù)據(jù)的存儲(chǔ)和查找消耗的時(shí)間,因此能夠很快定位到具體主題下的訂閱列表,提高匹配查找的效率。在具體的哈希函數(shù)的算法選取上,可以根據(jù)精確匹配的場(chǎng)景靈活進(jìn)行選取,避免因匹配數(shù)量過(guò)大導(dǎo)致訂閱誤差。對(duì)于字符數(shù)據(jù)匹配,利用訂閱樹(shù)結(jié)構(gòu)能有效地減少樹(shù)的深度,通過(guò)對(duì)關(guān)鍵字符的判斷,確定訂閱是單層匹配還是多層匹配,從而在相關(guān)主題下接收對(duì)應(yīng)的信息。
具體實(shí)現(xiàn)時(shí)在源代碼的訂閱部分加入判斷,確定后續(xù)訂閱匹配流程。使用哈希表時(shí),在源代碼中添加合適的哈希函數(shù)和哈希表的結(jié)構(gòu)體,如圖3所示。相比于只使用訂閱樹(shù)結(jié)構(gòu),哈希表利用自身特性通過(guò)算法函數(shù)將關(guān)鍵碼值映射到表中的一個(gè)位置,訂閱者訂閱的主題為表中key值,內(nèi)容則是從根節(jié)點(diǎn)到當(dāng)前節(jié)點(diǎn)共同組成的主題;value值為每個(gè)主題對(duì)應(yīng)訂閱者列表的地址。通過(guò)關(guān)鍵碼值對(duì)表直接進(jìn)行訪問(wèn),相比于樹(shù)結(jié)構(gòu),可以快速尋找并定位到具體的主題和訂閱列表,從而快速進(jìn)行匹配。哈希表在實(shí)際使用中也更容易控制表的長(zhǎng)度,有利于存儲(chǔ)。除了查找匹配,在執(zhí)行插入、刪除數(shù)據(jù)操作時(shí)也十分便捷,減少對(duì)數(shù)據(jù)操作的時(shí)間。
圖3 哈希表組成圖
實(shí)驗(yàn)數(shù)據(jù)的發(fā)布按照MQTT協(xié)議消息發(fā)布的服務(wù)質(zhì)量QoS=1進(jìn)行設(shè)計(jì)。由圖4可以看到,在發(fā)布者發(fā)送數(shù)據(jù)給代理服務(wù)器后,代理服務(wù)器會(huì)發(fā)送一個(gè)帶有PUBACK(如圖4中虛線框所示)的報(bào)文信息,從而確定代理服務(wù)器收到發(fā)布者所發(fā)來(lái)的報(bào)文。
圖4 QoS=1時(shí)的發(fā)布/訂閱流程
在表1所列軟硬件配置的服務(wù)器上搭建客戶端和Mosquitto,完成連接和配置。
表1 軟硬件配置
在服務(wù)器運(yùn)行正常后,分別對(duì)優(yōu)化前后的Mosquitto進(jìn)行測(cè)試。首先測(cè)試發(fā)布相同消息時(shí)代理服務(wù)器與客戶端訂閱匹配后接收到消息的時(shí)間,并增加發(fā)送消息的次數(shù)和消息量,查看性能變化。
見(jiàn)表2所列結(jié)果,通過(guò)發(fā)送時(shí)間戳并抓包測(cè)試客戶端發(fā)布消息后到代理服務(wù)器接收消息之間的時(shí)間間隔,經(jīng)過(guò)4次測(cè)試,每次發(fā)送JSON文件的數(shù)據(jù)量逐漸增大。對(duì)比優(yōu)化前后的響應(yīng)時(shí)間可以看出,修改后的結(jié)構(gòu)可以有效降低查找接收消息的響應(yīng)時(shí)間,平均降幅約為24%。
表2 測(cè)試運(yùn)行結(jié)果對(duì)比
對(duì)服務(wù)器進(jìn)行并發(fā)數(shù)測(cè)試,利用壓測(cè)工具進(jìn)行4次測(cè)試,在5 min內(nèi)均持續(xù)發(fā)送1萬(wàn)條消息。測(cè)試結(jié)果如圖5所示,并發(fā)接入數(shù)在優(yōu)化后明顯好于優(yōu)化前,平均增幅約為10%。
圖5 代理服務(wù)器并發(fā)接入數(shù)性能圖
本文針對(duì)所提的方法進(jìn)行了壓力測(cè)試。壓測(cè)時(shí)CPU占用率的結(jié)果如圖6所示,雖然優(yōu)化后訂閱機(jī)制的復(fù)雜度相較于優(yōu)化前有所增加,但增加的復(fù)雜度均能控制在合理水平區(qū)間,不影響服務(wù)穩(wěn)定運(yùn)行。
圖6 代理服務(wù)器CPU占用率
本文研究了消息代理服務(wù)器Mosquitto訂閱樹(shù)機(jī)制,分析了訂閱樹(shù)機(jī)制存在的缺陷,提出了基于訂閱樹(shù)和哈希表結(jié)合的優(yōu)化方法,在此基礎(chǔ)上進(jìn)行了測(cè)試驗(yàn)證。測(cè)試結(jié)果表明,優(yōu)化方法可以有效降低消息代理服務(wù)器的響應(yīng)時(shí)間,提升設(shè)備接入并發(fā)數(shù)量,使得消息代理服務(wù)器可以用更小耗時(shí)接收更多設(shè)備發(fā)送的數(shù)據(jù),有利于減小服務(wù)器使用數(shù)量,使其高效穩(wěn)定運(yùn)行。下一步的工作將繼續(xù)深入研究不同應(yīng)用場(chǎng)景下的優(yōu)化方法,并降低實(shí)現(xiàn)復(fù)雜度。
物聯(lián)網(wǎng)技術(shù)2021年11期