呂瓊帥,張國平
(平頂山學院 軟 件學院, 河南 平 頂山 4 67000)
Lucene是Apache軟件基金會項目組的子項目,是一個開放源代碼的全文檢索引擎工具包,即它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎、索引引擎和部分文本分析引擎。Lucene的目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene作為一個全文檢索引擎,其具有索引文件格式獨立于應用平臺、優秀的面向對象系統架構等突出的優點。但是,Lucene索引和查詢都不方便,容易受到索引文件數量的制約,這樣便會影響數據庫運行性能,降低檢索的效率。
隨著Web2.0技術的興起,NoSQL這個概念也逐漸被人們所熟悉。NoSQL最早出現于1998年,是非關系型數據庫的總稱,由Carlo Strozzi開發的一個輕量、開源、不提供SQL功能的關系數據庫[1]。2009年,Last.fm的Johan Oskarsson發起了一次關于分布式開源數據庫的討論,來自Rackspace的Eric Evans再次提出了NoSQL的概念[2]。目前主要的NoSQL產 品 主 要 有 MemCahe,Redis,Tokyo Tyrant,MongDB,HBase。NoSQL主要指非關系型、分布式、不提供ACID的數據庫設計模式,強調Key-Value Stores和文檔數據庫的優點,而并不是單純的反對RDBMS。并且NoSQL是以CAP、BASE以及最終一致性為其理論基礎,是針對目前大規模數據的高并發讀寫,高效存儲,高可用性等用戶需求而出現的一種較新的數據存儲機制。NoSQL之所以能夠快速發展,主要依賴于用戶對后臺數據庫的高并發讀寫的需求和對海量數據的高速訪問的需求。基于這樣一個優勢,本文將非關系型數據庫引入到Lucene全文檢索系統中,以此來應對大規模數據的高效存儲與高效檢索問題。
MemCache是由Danga Interactive公司開發的開源軟件,屬于臨時性鍵值存儲的NoSQL數據庫[3]。MemCache是通過散列表來存儲各種格式數據的鍵值存儲,所有的數據都被保存在內存中。
MemCache利用簡單的文本協議來進行數據通信,數據操作也只是類似于保存與鍵值相對應的值來進行簡單的處理。因此,通過Telnet連接MemCache,就可以進行數據的保存和讀取。MemCache的優勢主要就是其處理速度比較快。對于MemCache要處理的數據全部存儲于內存中,因此不需要訪問外部設備,那么在進行數據處理時就能夠比關系型數據庫高出很多的速度來運行。另外,MemCache在應用方面也比較簡單,在進行數據的操作時,主要是基于鍵值散列表的形式來進行的。但是隨著數據量的增加,MemCache的內存無法保存所有的數據,這時可以使用多臺服務器來運行MemCache,通過使用一致性散列算法[4]來將數據分散到多臺服務器上來運行MemCache。
一致性散列算法對各個服務器對應的散列值進行計算,把它們配置到一個圓周上。同時對各個數據對應的鍵的散列值進行計算,從鍵的散列值出發沿圓周向右,由距離該散列值最近的服務器來負責處理這條數據(數據的保存、讀取都由這個服務器來完成)。如圖1一致性散列分配方式。

圖1 一致性散列分配方式Fig.1 Consistent hashing allocation
MongoDB是10gen公司開發的一款以高性能和可擴展性為特征的開源軟件,它是NoSQL數據庫中面向文檔的數據庫[5]。MongoDB最大的特點就是無表結構。由于它無需定義表結構,所以對于任何Key都可以像關系型數據庫那樣進行復雜查詢等操作。MongoDB有比關系型數據庫更快的操作速度,而且可以像關系型數據庫那樣通過添加索引來進行高速處理。
MongoDB在保存數據的時候會把數據和數據結構都完整地以BSON(JSON的二級制化形式)的形式保存起來,并把它作為值和特定的鍵記性關聯。MongoDB采用面向文檔的數據模型,以文檔為單位存儲數據,每個文檔內的字段允許有不同的設置,可以動態修改數據結構模式。MongoDB使用自動分片機制實現分布式擴展,可以將數據庫中的集合、文檔分布存儲在多個數據庫節點。自動分片機制以集合為單位進行分片,選擇集合的一個或多個自動作為分片鍵,按分片鍵排序集合文檔,將集合分成多個塊存儲到不同的分片上。
對于基于Lucene的全文檢索系統來說,應用在高并發的讀寫和高效的存儲的情況下會使檢索的效率比較低,因為該系統需要提供多種格式的文檔的全文和元數據的存儲檢索查詢服務。對于中文的編碼問題,如果采用不同的編碼方式就會占用不同的存儲空間,檢索的效率就會降低。在高并發操作的時候,如果保存包含域的文件比較大時,在進行檢索時會浪費比較多的時間,檢索性能會有明顯的下降。而對于Lucene自身所采用的緩存機制來說,當該對象不存在了其對應的緩存并沒有回收。而該對象再次調用的時候又會重新分配新的內存,最終會出現內存泄露的問題。針對這些問題,本文給出一種具有高并發性和可擴展性的系統架構。
在對系統進行整體的設計時,將系統大體劃分為3層:上層的應用層,中間的數據服務層,底部的數據化持久層。如圖2整體架構。

圖2 整體架構Fig.2 Overall architecture
其中上層應用層主要指Web服務層(包含客戶端),用來接受和應答用戶請求,比如對文檔進行檢索、處理、存儲,并返回檢索信息等。中間數據服務層負責與底層交換數據同時屏蔽底層不同服務向上層提供統一的調用接口。底層服務包括文檔檢索服務實現層和數據持久化層,實現具體的業務邏輯,是系統的基礎。
在高并發讀寫,高效存儲的過程中,針對Lucene的低效存儲和面對較大的索引文件時檢索效率較低的問題,考慮減小索引文件的大小,將索引文件中的不重要的信息作為一個節點從索引文件中分離出去,而索引中僅存放較為重要的信息,如將ID和指向節點相關信息存放在MongoDB中,而將節點存放在MySQL中。這樣可以明顯加快檢索的速度,提高緩存的效率,而當需要訪問整個文件的信息時再從關系型數據庫中提取。具體方案如圖3所示。

圖3 NoSQL同步鏡像示意圖Fig.3 NoSQL Synchronous mirror
中間的數據服務層需要響應上層的用戶請求,并且需要調用下層服務,接受下層服務返回的數據,然后返回給上層用戶結果。在監聽用戶的請求時,本文選擇了Apache MINA作為中間層的解決方案,MINA通過Java NIO提供了一種抽象的異步通訊API,使用MINA能夠便捷的進行非阻塞I/O而不用考慮過多的傳輸細節,并且是事件驅動的方式[6]。在監聽到請求后需要對事件進行處理,本系統選擇了規則引擎Drools作為事件處理邏輯單元的解決方案。Drools實現了邏輯與數據的分離,數據保存在系統對象中,邏輯保存在規則中,可以使用更接近自然語言的方式來編寫規則[7]。并且規則相對于編碼更容易對復雜問題進行描述。因此,使用規則引擎滿足上文描述的事件處理邏輯的需求,可以用規則引擎來實現中間數據服務層的核心部分。中間數據服務層的執行流程如圖4所示。

圖4 服務層運行流程Fig.4 Service layer running processes
上層的應用層主要用來接收用戶的請求,并利用應用層的緩存層來暫存檢索的結果,為了提高檢索的速度,本文主要采用MemCache來構建應用層的緩存框架,因為MemCache的主要優勢就是其極快的處理速度,如果緩存中存有數據,根本不需要去進行I/O操作。另外在使用MemCache的過程中,其安裝使用也比較方便,如果在運行過程中遇到難以處理的問題,只要重新啟動MemCache就可以恢復到初始狀態。為了應對數據量的巨增,在系統架構時通過多臺服務器來運行MemCache。

圖5 MemCache使用方法Fig.5 The method used MemCache
將三層進行整合后,當客戶端發起查詢請求時,會先去查看緩存中是否含有查詢的請求,如果有則直接返回結果,反之,根據查詢分析器和規則庫將查詢請求規范化后,搜索數據庫中的索引文件,把結果返回給客戶端,同時將規范化后的客戶請求保存在緩存中。
實驗主要從檢索的響應時間來測試該系統架構的性能。如圖6,其中橫軸表示文檔的數量,縱軸表示檢索時間。其中LST表示僅在使用Lucene時掃描索引文件的時間,NST表示基于NoSQL的掃描索引文件的時間;LRT表示僅在使用Lucene時搜索的響應時間,NRT表示基于NoSQL的搜索響應時間。

圖6 響應時間Fig.6 Response time
從圖6的實驗結果可以看出,隨著文檔數量的增加,僅使用Lucene的全文檢索系統和基于NoSQL的全文檢索系統的響應時間都在逐漸增大,但Lucene的全文檢索系統響應時間增加的比較明顯,基于NoSQL的全文檢索系統的響應時間大體上保持相對穩定。
該系統將NoSQL技術引入到Lucene的全文檢索過程中,克服了Lucene在應對數據的高并發性方面檢索速度慢的缺陷。系統在架構時采用分層的設計思想,使系統層次間具有低耦合,層次內部具有高內聚的特點,通過實驗表明該系統在應對高并發性和高效檢索問題時具有較快的響應速度,且系統運行過程中較為穩定。
[1]Lith, Adam,Jakob Mattson.Investigating storage solutions for large data:A comparison of well performing and scalable data storage solutions for real time extraction and batch insertion of data[D].oteborg Sweden:Chalmers University of Technology,2010.
[2]謝毅.NoSQL非關系型數據庫綜述[J].先進技術研究通報,2010,4(8):46-50.XIE Yi.NoSQL Summary of non-relational databases[J].Bulletin of Advanced Technology Research,2010,4(8):46-50.
[3]陸嘉恒.大數據挑戰與NoSQL數據庫技術[M].北京:電子工業出版社,2013.
[4]姚琳,張永庫.NoSQL的分布式存儲與擴展解決方法[J].計算機工程,2012,38(6):40-42.YAO Lin,ZHANG Yong-ku.Solution of NoSQL distributed storage and extension[J].Computer Engineering,2012,38(6):40-42.
[5]沈姝.NoSQL數據庫技術及其應用研究[D].南京:南京信息工程大學,2012.
[6]曾冠東.基于MINA構建簡單高性能的NIO應用[J].程序員,2008(2):120-123.ZENG Guan-dong.Building a simple high-performance NIO application based on MINA[J].Programmer,2008(2):120-123.
[7]劉金龍.drools規則引擎模式匹配效率優化研究及實現[D].成都:西南交通大學,2007.