任軍鋒,孟亞旗
(上海工業自動化儀表研究院有限公司,上海 200233)
隨著數據信息化發展速度的加快,產生了很多全文本類的大數據場景。對于這些數據的精準、快速查詢,已成為常規需求[1]。由于數據量大,數據集中在一個中心,會給后期的業務查詢帶來巨大壓力。分布式存儲-查詢是解決這類問題的常用解決方案。存儲和查詢是分布式查詢的必要步驟,只有合適的數據存儲結構和良好的查詢框架相配合,才能組建高效、準確的查詢系統。同時,分布式查詢的整體架構設計必須有較好的擴展性,即使數據量增大,也可以通過增加硬件設備、擴展存儲節點的方式解決數據查詢的性能問題[2]。
數據的存儲與查詢是前端業務的基礎。系統程序的高內聚、低耦合,是系統的必要屬性。高內聚可以讓模塊部分專注于模塊本身,重要核心內容對外界透明,而又不依賴于外部。低耦合則是盡可能減少和外部模塊的聯系,接口設計越簡單,協同開發的效率越能大幅提升[3]。
RabbitMQ是典型的前后端通信的消息隊列通道。SocketServer可以應對多連接的TCP/UDP請求。這兩者的結合,能夠為解決分布式查詢問題提供有效幫助。本文通過對分布式查詢軟件架構的設計和開發的研究,為解決類似查詢全文類數據問題提供了有效參考。
文本類數據的可追溯查詢:文本類數據經過預處理和分析關聯后,形成結構化的信息,存儲到關系型數據庫中。Web業務端可根據提取的結構化的內容追溯到原始文本數據,供頁面顯示原始數據詳情[4]。滿足該需求需要分5步實現。①原始數據文件存儲:為了更好地利用磁盤資源、減少數據庫內容的占用量,原始數據采用本地或者中心集中壓縮存儲的方式。②結構化數據和原始文件關聯性:結構化數據字段中記錄原始文件路徑和位置。③分布式架構設計的擴展性:采用QueryAgent和QueryService的二級架構。④前后端通信接口:選擇性能健壯、耦合度低的通信服務接口。⑤查詢并發和性能:采用高并發異步的處理模型,增加索引緩存設計[5]。
RabbitMQ是一套開源(mozilla public license,MPL)的消息隊列服務軟件,采用以高性能、健壯以及可伸縮性而聞名的 Erlang 寫成[6]。軟件系統的前端和后端可以通過該消息隊列傳遞數據,降低前后端耦合度。RabbitMQ的具體特點包括高可靠性、靈活路由、擴展性強、高可用性、多種協議多語言支持等[7]。它的五種模式為simple、work、fanout、route、topic。根據現有需求,路由模式更適合場景。Web業務端發送消息到交換機exchange,同時要指定route路由的key。此時,數據獲取端將queue隊列綁定到交換機exchange,同時也需要綁定到route路由的key。后端從隊列中取出消息后,分析消息內容和查詢條件,然后下發消息到指定的查詢服務節點即可[8]。
SocketServer是用于創建網絡服務器的python標準庫常用模塊。該模塊是一個基本的socket服務器框架,使用threading處理多客戶端連接,使用seletor處理高并發訪問[9]。SocketServer剛好滿足了QueryService功能實現的要求。當有多個查詢任務發布到同一臺QueryService節點時,查詢任務不會因此阻塞。SocketServer的異步機制不僅可以很好地應對多客戶連接查詢的要求,而且實現過程對使用者透明,開發者僅需關注自身業務層數據內容。
系統架構如圖1所示。

圖1 系統架構圖
從圖1可以清晰地看到,整個系統分為Web業務層、QuerAgent代理層和QueryService服務層。Web服務器通過RabbitMQ通道將查詢條件發送給QueryAgent代理層。QueryAgent根據查詢條件和規則查找算法,找到數據所在的QueryService機器。QueryService根據查詢條件,將本地存儲的原始日志信息通過socket反饋給QueryAgent代理層。QueryAgent代理層將查詢結果按照通信接口要求重新組織,發送到RabbitMQ中。Web服務器從RabbitMQ中提取信息,然后在頁面顯示。
另外,以上架構的層次設計可以保證程序有較好的擴展性。當數據量增加,只需增加相應的QueryService數量,即可滿足一般的擴展需求。QueryAgent代理層的設計,也讓系統的擴展性更加豐富。例如,可以安裝多個查詢代理,分別查詢、處理不同業務類型的數據。Web業務層、QueryAgent層和QueryService層都可以設計各自的緩存機制,從多個方面提高查詢的效率。
①索引設計。
對于待查詢的數據的索引,設計的合理性將直接影響查詢的效率。雖然沒有萬能的索引設計公式,但是好的索引結構都具有唯一性、分層分塊存儲、支持增量索引的特點[10]。因此,必須密切結合具體的業務場景,分析業務自身特點,找到系統本身的共性和個性,設計最適合自身業務的索引結構。例如:該分布式數據查詢系統是用于追溯查詢原始文本數據的。原始全文本類數據經過處理分析結構化后存入數據庫表。前端業務層可以通過結構化的數據庫表直接查找到原始文本類內容,以校驗結構化處理的準確性。所以在處理結構化數據時,就將該條原始數據的位置信息作為結構化數據的一個字段記錄下來,作為后續精確查找的條件。
②緩存機制。
對于查詢系統,良好的緩存設計可以大幅提高查詢效率、提升用戶體驗。緩存設計的核心是命中率高、復用性強、占用空間少。例如:本系統的緩存設計在QueryAgent處,查詢條件作為緩存的key,遇到相同查詢條件,數據可以直接反饋之前的查詢結果,而不需要再次去二級節點查詢服務處查詢。
③并發性。
對于批量的查詢,可以支持高并發,充分利用CPU資源,快速反饋結果。多線程、多進程、分布式的實現方式是解決該問題的常用有效方法。例如:在此實例中,正對批量查詢會創建多個線程,同時執行查詢任務。查詢服務結點部分ServerCenter_Content中運用SocketServer類,可以很好地處理并發的連接請求。
④可擴展性。
在設計整體系統時,要考慮到后續數據可能快速增加后帶來的查詢壓力問題。在系統架構設計初期,需要充分調研需求,仔細分析業務,做好層次模塊劃分、分層設計。當數據量增加時,不用調整軟件架構,僅增加服務器設備就可以解決數據量大的問題和性能瓶頸。
⑤接口通信設計。
對于接口通信設計,在滿足數據傳輸要求的同時要盡量簡單,從而降低與其他業務聯合開發的耦合性。例如:該系統在前后端通信接口部分,主要應用RabbitMQ消息隊列,傳輸前后端查詢條件和結果。這樣就不用單獨開發通信接口。復用開源成熟的通信接口,可以讓前后端的開發專注于業務。在后端內部數據通信,應用了SocketServer。該模塊對Socket類作了更好的封裝,增加了并發處理和異步等機制,簡化了通信編碼開發[11]。
數據來源是各地實時上傳的數據文件,接收程序會按照日期時間目錄分布存儲。如:2019-09-08 10∶22∶15接收的數據文件是171.125.3.157.log,將存儲在171.125.3.157服務器的/datastorage/20190908/10/22目錄下。
本文設計的AgentServer查詢代理類如表1所示。

表1 AgentServer查詢代理類
RabbitMQ消息請求接口內容為:
json_info = {"mayjorType":"",#主模塊類型
"taskCount":"1",#批量任務數
"commitTime":"now",#批量任務提交時間
"tasks":{"taskName":"QueryAgent",#任務名稱
"createTime":"NOW",#任務創建時間
"taskID":"2",#任務ID(唯一)預留字段
"subType":"Query",固定Query
"detail":{}
}
}
RabbitMQ消息響應接口內容為:
message = {
′resType′:′response′,
′result′:[
{ ′code′:1,
′message′:′successful′,
′mayjorType′:′l′,
′subType′:′QueryAgent′,
′taskName′:′Query′,
′taskID′:′1′,
′resTime′:‘2019-05-06 14:18:14’,
′detail′:{ ′redisKey′:′′,′Result′:[]}
}
]
}
按照以上系統架構設計軟件,編碼開發完成后,需要對整個軟件需求的功能進行部署測試。建議至少準備2臺linux服務器:1臺部署QueryAgent 查詢代理機,1臺部署ServiceCenter_content程序查詢節點機,待查詢的原始數據按照以上存儲規則,存放在查詢節點機上。部署測試主要包含4個部分:①查詢結果準確測試;②緩存機制加速效果測試;③并發查詢測試;④系統快速可擴展性測試。
查詢結果準確率測試是本系統軟件設計的基本功能要求。緩存機制加速效果測試,是為了檢驗提高的查詢效率。針對歷史查詢可以快速反饋結果的測試,是系統用戶體驗的重要保證。并發查詢測試是指系統中同時有多個用戶批量查詢數據后,能及時、準確反饋查詢結果的測試,是系統可靠性、健壯性的重要體現。系統快速可擴展性測試,在系統中的增加ServiceCenter_content查詢節點機,在不修改系統架構和程序代碼的基礎上就可以滿足增大的基礎數據量查詢需求,且性能幾乎不受影響。
在信息大爆炸的時代,人們的工作和生活正在被大數據影響和改變。用戶如何在海量的數據中查詢到想要的信息變成一個尤為迫切的需求[12]。本次基于RabbitMQ和SocketServer的分布式查詢系統設計,為解決數據的查詢提供了很好的解決思路。該分布式查詢系統的設計和實現,通過詳細的需求調研、分析數據、設計開發、部署測試,很好地滿足了用戶對原始數據追溯查詢的需求。此次軟件架構的設計和開發,為后續要解決查詢原始數據問題提供了實例。后續的設計和開發者,可以根據實際需求,參考以上設計和分析問題方法,解決實際問題。