傅巍瑋,李仁發(fā),劉鈺峰,黃松立
(1.湖南大學嵌入式系統(tǒng)及網(wǎng)絡實驗室 長沙410082;2.淘寶(中國)有限責任公司 杭州315100)
互聯(lián)網(wǎng)信息技術的高速發(fā)展使人們更加關注如何以最快的時間獲取實效數(shù)據(jù),并從中挖掘到有價值的信息。獲取實時資訊的方法有兩種。一是建立實時數(shù)據(jù)庫[1],保證數(shù)據(jù)的強一致性(ACID)和高可用性,但其在分布式環(huán)境下的擴展能力較為有限;二是建立實時搜索引擎,不僅有理論價值,同時有重大的應用價值[2]。傳統(tǒng)的信息搜索技術發(fā)展非常成熟,但是在查詢精度和不同查詢需求上存在許多不足[3],不能滿足信息的實時搜索需求。實時搜索是傳統(tǒng)搜索引擎的擴展和延伸,可以分為通用實時搜索引擎[4]和垂直實時搜索引擎[5]。垂直搜索引擎針對某一領域行業(yè)的搜索,特點是專、精、深,實時搜索的研究大多集中于垂直搜索領域,如在圖片搜索[6]和物聯(lián)網(wǎng)領域的應用[7]。實時搜索已成為當前搜索引擎領域的熱點問題,其核心概括為實時數(shù)據(jù)獲取和實時索引構建兩方面。相比傳統(tǒng)搜索研究,垂直搜索數(shù)據(jù)來源相對簡單,因此垂直實時搜索的難點問題是分布式環(huán)境下的實時索引構建。實時索引構建主要指的是在大規(guī)模高并發(fā)的分布式環(huán)境下,即時提交實時數(shù)據(jù)構建索引,保證實時數(shù)據(jù)即時展示以及分布式數(shù)據(jù)的一致性和容災[8]。
針對這一難點問題,本文在分布式搜索技術[9]基礎上提出一種基于Solr[10]的分布式實時檢索模型,模型的創(chuàng)新之處如下。
·引入自定義多維度的分組規(guī)則構建分布式索引數(shù)據(jù)??筛鶕?jù)實際需求對索引進行多維度的切分,將大型索引切分成獨立的集群組,搜索時通過相應的路由規(guī)則定位至索引信息所在的m×n分布式集群組,減少索引搜索時間,提高搜索性能。
·提出一種新的實時搜索模型,采用內(nèi)存與磁盤索引相結合的多索引機制。通過全量的方式定期建立主磁盤索引,保證數(shù)據(jù)的完整性。實時信息以增量方式先寫入內(nèi)存,內(nèi)存索引超出設定閾值后復制寫入磁盤,形成從磁盤索引,不與主索引合并,減少索引合并時間開銷。同時查詢內(nèi)存和磁盤索引,提升搜索響應時間。
·解決分布式環(huán)境下的索引數(shù)據(jù)容災問題。引入CommitLog日志機制,持久化索引元數(shù)據(jù),改進Solr的Master/Slave(主備)模型,保證數(shù)據(jù)的一致性和可用性。
分布式實時搜索模型由3部分組成,如圖1所示。
·搜索功能實現(xiàn):搜索請求分為查詢、更新、添加、刪除4種,分別定位到分布式集群的一組或者多組服務器。
·分布式m×n系統(tǒng)模型構建:分布式集群組采用m×n模型,每一組集群內(nèi)采用Master/Slave模型保證單組數(shù)據(jù)的一致性和搜索服務的可用性。
·索引數(shù)據(jù)構建:索引構建采用主磁盤索引+內(nèi)存索引+從磁盤索引相結合的模型,保證最新的數(shù)據(jù)即時展現(xiàn),實現(xiàn)搜索的實時性。實時索引的請求先寫CommitLog日志,保證實時索引的數(shù)據(jù)容災性。
分布式系統(tǒng)是解決目前大規(guī)模海量數(shù)據(jù)和高并發(fā)請求的最有效方式。本系統(tǒng)采用分布式m×n的部署模型切分海量數(shù)據(jù)建立索引,實現(xiàn)高并發(fā)搜索請求量的隨機軟負載均衡,提升搜索系統(tǒng)性能。在索引量和搜索請求增加的情況下,動態(tài)添加行列的機器數(shù)量保證存儲負載和搜索性能。其中,n列指系統(tǒng)劃分為搜索服務器集群的個數(shù),m行指單個搜索服務器集群包含搜索服務器的臺數(shù),m≥1且n≥1。m×n模型建立過程如下。
(1)自定義切分規(guī)則
根據(jù)系統(tǒng)需求,設定自定義的索引切分規(guī)則進行Group Filter分組路由,例如分組規(guī)則用生成的索引Docment文檔的Field域userId取模進行分組。分組規(guī)則不僅可以是單維,也可以是多維,即在m×n二維分組的基礎上進行擴展,多維數(shù)組與一維數(shù)組存儲機制一致,如先按userId取模分組后,再以用戶所在的省份進行分組。
(2)確定m×n行列值
m和n的行列值取決于兩個因素。
·搜索服務器單機負載能力。單機的索引數(shù)據(jù)容量由磁盤容量決定。建立新索引的過程中涉及索引的合并,舊的索引繼續(xù)提供索引服務,此時的磁盤空間為:一份新索引+一份正提供服務的索引+索引合并所需磁盤空間,磁盤容量至少為索引數(shù)據(jù)的3倍。單機能承受的搜索請求量通過壓力測試獲取。當機器負載(load)值等于搜索服務器的CPU核數(shù)時,服務器所能承受的TPS(每秒請求數(shù))為壓力測試的峰值,如對于4核的服務器,通常在load=4時的TPS為其單機所能承受的最高值。
·分布式系統(tǒng)索引總量和搜索請求總量。索引總量用S表示,單機承載索引量用T表示,搜索請求總量用Q表示,單機承載搜索請求量用R表示,X表示機器增量,在搜索的熱點數(shù)據(jù)相應組添加服務器,保證可用性,則m、n可用下式計算:
(3)建立分布式集群
根據(jù)索引切分規(guī)則和m、n的行列數(shù),建立分布式搜索服務器集群。所有搜索服務器均提供搜索服務,搜索請求隨機發(fā)送到組內(nèi)的任一服務器。在同一組搜索服務集群中,每一臺搜索服務器分別向組內(nèi)其他服務器發(fā)布感知服務,確保兩兩感知。單組集群內(nèi)部,設定一臺Master服務器,其他均為Slave服務器。Master服務器負責主索引的建立和寫CommitLog日志文件,Slave服務器從Master服務器中同步主索引,同步CommitLog日志建立內(nèi)存索引。通過Master/Slave模型保證單組的索引數(shù)據(jù)容災性,在組內(nèi)某一搜索服務器宕機的情況下保證搜索服務的可用性。
索引分為3個部分:主磁盤索引、內(nèi)存索引、從磁盤索引。磁盤+內(nèi)存的索引結構保證新增索引即時展現(xiàn)。寫內(nèi)存索引前先寫CommitLog日志,持久化索引數(shù)據(jù),保證內(nèi)存索引數(shù)據(jù)不丟失。內(nèi)存索引到達閾值后刷入從磁盤索引,保證可用性。索引的構建采用全量dump+實時增量dump的模型構建。全量dump采用時間周期任務定期執(zhí)行,實時增量dump由實時調(diào)用接口生成,下面是實時索引構建的詳細設計。
(1)主磁盤索引構建
·搜索服務器定時觸發(fā)全量dump程序。系統(tǒng)從數(shù)據(jù)源獲取索引數(shù)據(jù),數(shù)據(jù)源可以是網(wǎng)絡爬蟲抓取的信息、各種存儲系統(tǒng)(數(shù)據(jù)庫、文件、nosql系統(tǒng)等)。索引建立采用迭代器模型,利用Data Provider接口,首先利用has Next()判斷下一條語句是否存在,存在則用next()方法取下一條數(shù)據(jù),構建并返回一條Map記錄,直至has Next()方法返回為false,結束整個迭代過程。Map記錄對應一篇索引文檔,Map的
·時間點設置:主索引構建過程開始時,記錄一個時間點checkPoint。主索引建立完成后,提供搜索的服務將從舊索引替換到新索引,但是新索引建立過程中,會有增量的實時索引產(chǎn)生,因此需要補全在全量執(zhí)行期間的增量數(shù)據(jù),通過時間點機制從后補全實時索引。
·Slave服務器構建主索引:Master服務的主索引構建完成后,通知Slave服務器進行主索引的拷貝,并將checkPoint傳遞給Slave服務器,Slave服務器完成索引的構建工作后通知Master服務器,新的索引向外提供搜索服務。
(2)實時索引構建
實時索引構建包含內(nèi)存索引構建和從磁盤索引構建2部分,實現(xiàn)過程如下。
·實時更新請求。實時請求可以來自于數(shù)據(jù)源(與主索引相同),也可以來自客戶端的實時接口調(diào)用。以實時接口調(diào)用為例,客戶端調(diào)用Real-time Bean類的實時方法發(fā)送請求。實時請求方法分為Add(添加)、Update(更 新)、Delete(刪 除)、mAdd(批 量 添 加 )、mUpdate(批量更新)、mDelete(批量刪除)。服務器端接收實時請求,將實時請求封裝為Document Request對象添加到CommitLog日志文件中。
·CommitLog日志建立。所有的實時請求都會寫入Master服務器的CommitLog日志中,持久化索引請求。搜索服務器啟動時創(chuàng)建實時索引的構建進程Real-time Job,不斷輪循CommitLog日志,一旦有新的記錄產(chǎn)生即進行寫索引操作,根據(jù)請求類型的不同,分別調(diào)用Solr的Update Handler的相應方法建立內(nèi)存索引。
·從磁盤索引建立。內(nèi)存索引受限于內(nèi)存大小,所以需要設定閾值,防止內(nèi)存索引過大撐爆內(nèi)存或者影響其他應用。當內(nèi)存索引達到閾值時,新開一個內(nèi)存索引,新來的實時請求寫入新的內(nèi)存索引,同時將舊的內(nèi)存索引刷新至磁盤。利用內(nèi)存索引與磁盤索引結構完全相同的特性,調(diào)用Directory的copy方法直接將內(nèi)存索引拷貝至磁盤,形成從磁盤索引,提升搜索性能,實現(xiàn)立即搜索。
·內(nèi)存索引恢復機制。如果服務器宕機或者重新部署導致服務器重啟,當前的內(nèi)存索引會造成數(shù)據(jù)丟失。設定宕機時間恢復點記錄CommitLog日志位置偏移值,新的從磁盤索引生成時,更新一次宕機時間恢復點信息。服務器重啟時從最近的宕機時間恢復點開始讀取CommitLog日志,恢復內(nèi)存索引。通過CommitLog日志機制保證內(nèi)存索引數(shù)據(jù)的容災。
系統(tǒng)一共提供4種功能,包括查詢、新增、更新、刪除。查詢不會修改索引數(shù)據(jù)結構,其他3種操作都會造成索引數(shù)據(jù)的修改,且有相應的批量操作方法。
(1)搜索功能實現(xiàn)
用戶發(fā)出搜索請求后,通過路由規(guī)則獲取索引所在分布式搜索服務器組的集合。如果是單組搜索,需要對當前所有的索引進行搜索,包含主磁盤索引、內(nèi)存索引、從磁盤索引,搜索結果過濾掉已被刪除的文檔。被刪除文檔的docId存儲在delList集合中。多組則利用Solr的shard概念對多組的結果集作合并操作。Solr服務是通過HTTP的方式提供服務,索引合并也都是通過HTTP方式發(fā)出請求進行合并,本系統(tǒng)對此作了改進。任意選定分組集中的一組,通過TCP/IP協(xié)議進行訪問,此時利用Solr提供的Embedded Solr Server獲取當前組索引,并向其他組發(fā)送TCP/IP請求,獲取索引數(shù)據(jù)并進行索引的merge操作,提高索引獲取速度。
(2)添加、刪除、更新功能實現(xiàn)
·添加功能實現(xiàn)??蛻舳税l(fā)出Add命令,將其封裝成添加請求寫入CommitLog日志文件中。Index Build Job構建索引時進行判斷,如為Add Document Request請求,提取索引數(shù)據(jù)信息轉(zhuǎn)換為Solr的Add Update Command對象,最后調(diào)用Solr的Update Handle的Add Doc()命令,實現(xiàn)索引數(shù)據(jù)的添加。
·刪除功能實現(xiàn)??蛻舳税l(fā)出Delete命令,將其封裝成刪除請求 Delete Document Request寫入CommitLog日志文件中。在Lucene搜索引擎中有Index Writer和Index Reader兩個對象可以做刪除動作,區(qū)別在于Index Writer實例中刪除的內(nèi)容被緩存起來,并不會馬上生效。搜索引擎接收實時刪除請求后,如果待刪除的文檔在內(nèi)存中,則用Index Writer直接進行刪除,否則在磁盤索引(即主索引和從索引)做標志刪除,將文檔保存至待刪除的集合delList中。在內(nèi)存索引提交時,調(diào)用Index Writer的commit()方法,再調(diào)用磁盤索引的Index Reader方法逐個刪除delList集合的元素。
·更新功能實現(xiàn)。與Add命令相同,客戶端發(fā)出Update命令會被封裝為Update Document Request請求,寫入CommitLog日志中。Index Build Job構建索引時,將索引數(shù)據(jù)信息轉(zhuǎn)換為Add Update Command,同時設置 Allow Dups為 false,即不允許索引數(shù)據(jù)重復。此時Solr會首先判斷索引是否已存在,有則刪除,然后進行添加操作,完成更新。
實驗由10臺搜索服務器組成,分為5組,每組一主一備。搜索服務器配置為Intel?Xeon?4核CPU E5520@2.27 GHz、內(nèi)存4 GB、60 GB硬盤7 200轉(zhuǎn)。索引總量為60 GB、單機12 GB,實驗數(shù)據(jù)取平均值。
工程實現(xiàn)的原型系統(tǒng)為Xsolr,對比系統(tǒng)為Solr,數(shù)據(jù)集為4 000萬個文檔,每個文檔由22個域構成,平均大小為0.03 KB,測試工具為Load Runner。實驗結果分兩部分,第一組實驗為Xsolr與Solr系統(tǒng)的性能指標對比,結果見表1,第二組實驗為Xsolr的數(shù)據(jù)一致性與容災,如圖2所示。
·實時響應性能。由表1可以看出,Xsolr的TPS和響應時間在4種測試條件下的性能均好于Solr。實時更新的請求響應時間均在1 s以內(nèi)。因為Xsolr更新操作在內(nèi)存進行,索引在內(nèi)存進行建立,而且不與磁盤索引進行合并,同時搜索內(nèi)存和磁盤索引,減少磁盤I/O,加速了實時索引數(shù)據(jù)展示的速度。
·負載分析。在系統(tǒng)負載接近的情況下,Xsolr的CPU更加消耗資源。因為Xsolr會建立內(nèi)存索引,實驗環(huán)境下占用大量內(nèi)存,最高時達到1 GB。CPU使用率最高在30%左右,此時索引的更新TPS高達2 100,大量占用內(nèi)存,但是機器負載仍小于4,在可接受的范圍內(nèi)。
·數(shù)據(jù)一致性。如圖2所示,前15 s內(nèi),單機分別進行插入、更新、刪除操作,Master/Slave服務器數(shù)據(jù)保持一致,有極細微區(qū)別。實時操作時,Slave不間斷地從Master機器中拉取增量CommitLog日志文件,進行消費創(chuàng)建實時索引,保證主備服務器數(shù)據(jù)的一致性。但是由于CommitLog是順序?qū)懭?,且從Master機器拷貝文件有一定的網(wǎng)絡開銷,所以會出、現(xiàn)極細微的區(qū)別,在毫秒級別實現(xiàn)最終一致性,對系統(tǒng)整體服務影響極小,在可接受的范圍內(nèi)。
表1 Xsolr與Solr實驗結果對比
·數(shù)據(jù)容災及完整性。17 s時,Master服務器隨機插入1 000條記錄,此時內(nèi)存索引未達到閾值,不刷入從磁盤索引。30 s時,Slave服務器恢復服務,其索引記錄數(shù)與Master相同。35 s后Master服務器宕機,60 s后恢復啟動,其索引記錄數(shù)與Slave相同,且符合最初插入的1 000條記錄數(shù)。Xsolr通過CommitLog日志持久化實時數(shù)據(jù),設置宕機恢復點。服務器宕機恢復時,讀取離Check Point最近的CommitLog日志記錄偏移量,從偏移量處開始重建內(nèi)存索引,保證數(shù)據(jù)的完整性,實現(xiàn)數(shù)據(jù)容災。
實驗結果表明,本模型滿足系統(tǒng)的實時性需求,同時在大數(shù)據(jù)量和高并發(fā)環(huán)境下保證了數(shù)據(jù)的一致性和數(shù)據(jù)容災,證明了系統(tǒng)模型的可行性。
本文主要研究了分布式實時搜索引擎,并基于Solr進行了實現(xiàn)。重點解決搜索引擎在大數(shù)據(jù)量高并發(fā)分布式環(huán)境下的實時性和數(shù)據(jù)容災問題。模型目前還存在一些問題,如Master/Slave模型中寫操作都是作用于Master服務器,其宕機會造成實時信息更新失敗。下一步的工作從以下方面著手:改進當前的實時模型,實現(xiàn)單組搜索服務器Master/Slave去角色化,進一步提高實時模型的可用性;研究利用SSD磁盤代替普通SATA硬盤作高速存儲,進一步提高實時搜索性能。
1 Nizar Idoudi,Claude Duvallet,Bruno Sadeg.How to model a real-time database.In:Proc of IEEE International Symposium on Object/Component/Service-Oriented Real-TimeDistributed Computing,2009
2 Bernard J Jansen,Zhe Liu,Courtney Weaver,et al.Real time search on theWeb:queries,topics,and economic value.Information Processing and Management,2011
3 曾春,邢春曉,周立柱.基于內(nèi)容過濾的個性化搜索算法.軟件學報,2003(5)
4 Daniel Peng,Frank Dabek.Large-scale incremental processing using distributed transactions and notifications.In:Proc of the 9th USENIX Conference of OSDI,2010
5 Wu Y,Shou L,Hu T,et al.Query triggered crawling strategy:build a time sensitive vertical search engine.Cyberworlds,2008
6 Jingyu Cui,Fang Wen,Xiaoou Tang.Real time Google and live image search re-ranking.In:Proc of the 16th ACM International Conference on Multimedia,2008
7 Gershenfeld N,Krikorian R,Cohen D.The Internet of things.Scientific American,2004,291(4):76~81
8 Seth Gilkn,Nancy Lynch.Brewer's conjecture and the feasibility of consistent,available,partition-tolerant Web services.Sinact News,2002,33(2)
9 姚樹宇,趙少東.一種使用分布式技術的搜索引擎.計算機應用與軟件,2005,22(10)
10 Apache.SOLR.http://lucene.apache.org/solr/