郭喬進 胡 杰 梁中巖 宮世杰
(中國電子科技集團公司第二十八研究所 南京 210014)
隨著互聯(lián)網(wǎng)的發(fā)展以及Web 2.0的興起,超大規(guī)模以及高并發(fā)的純動態(tài)型網(wǎng)站日漸成為主流,由于網(wǎng)站在數(shù)據(jù)存取過程中有著實時性等剛性需求的原因,致使關(guān)系型數(shù)據(jù)庫越來越不足以勝任,這使得目前NoSQL數(shù)據(jù)庫[1]慢慢成了人們所關(guān)注的焦點。HBase[2~3]作為一種分布式 Key-Value 數(shù)據(jù)庫,能夠應(yīng)對海量數(shù)據(jù)分布式存儲和快速獲取,同時具有高可用性和強大的橫向擴展能力。
然而,在面對大規(guī)模的工程應(yīng)用時,直接使用HBase API進行數(shù)據(jù)庫的訪問,需要開發(fā)人員耗費大量的時間、精力來編寫大量重復(fù)的數(shù)據(jù)庫訪問代碼,導(dǎo)致開發(fā)效率降低,也更容易出錯;另一方面,HBase并不支持數(shù)據(jù)段的索引,只能根據(jù)鍵值進行查詢,而使用Hive[4]等進行查詢則由于需要啟動MapReduce[5~6]任務(wù),無法滿足 Web用戶的實時查詢需求。
針對上述問題,我們基于Java的反射和注解技術(shù),構(gòu)建了一套HBase-ORM(Object Relational Mapping)框架,將數(shù)據(jù)庫層與數(shù)據(jù)訪問層進行分離,提高開發(fā)效率,減小出錯率;同時通過利用ES[7]對HBase中的每列數(shù)據(jù)根據(jù)不同的類型來建立索引,實現(xiàn)了文本的模糊查詢、數(shù)值的區(qū)間查詢、經(jīng)緯度的范圍查詢以及圖像的相似度查詢,從而滿足Web用戶針對不同數(shù)據(jù)類型的實時查詢需求。
在對關(guān)系數(shù)據(jù)庫進行訪問和操作時,通常使用ORM框架來負責(zé)數(shù)據(jù)的持久化。例如Hibernate[8]是目前最流行的ORM框架,是連接Java對象模型和關(guān)系數(shù)據(jù)模型的橋梁,它對JDBC進行了輕量級的封裝,不僅提供ORM映射服務(wù),還提供數(shù)據(jù)查詢和數(shù)據(jù)緩沖功能,實現(xiàn)了業(yè)務(wù)邏輯對數(shù)據(jù)的透明訪問。對于Web應(yīng)用而言,數(shù)據(jù)訪問對象隔離了不同數(shù)據(jù)源之間的差異,從而實現(xiàn)了業(yè)務(wù)邏輯層與數(shù)據(jù)源之間的解耦。
對于NoSQL數(shù)據(jù)庫,由于數(shù)據(jù)庫類型的多樣性,目前尚無統(tǒng)一的ORM框架[9],本文主要關(guān)注HBase 的 ORM 框架[10]。Phoenix[11]是一個開源的HBase查詢引擎,其通過將SQL查詢轉(zhuǎn)換為一個或多個HBase Scan來獲取數(shù)據(jù),直接使用HBase API,利用Coprocessor和Filter進行數(shù)據(jù)查詢,試圖規(guī)避MapReduce,從而減小時延。然而由于Coprocessor和Filter的自身能力受限,完全拋棄MapReduce使其在面對復(fù)雜查詢和大數(shù)據(jù)量的查詢時性能受限。SimpleHBase[12]是一個輕量級的 HBase 中間件,支持數(shù)據(jù)類型映射、操作轉(zhuǎn)換,通過封裝HBase的Filter支持類SQL的查詢,與Phoenix類似,其同樣受限于Filter的處理能力。
為了解決HBase的海量數(shù)據(jù)復(fù)雜查詢問題,另一種解決思路就是對HBase中的每列數(shù)據(jù)建立索引。目前支持海量數(shù)據(jù)分布式索引的框架主要有兩個,分別是 Solr[13]和 ES。Solr是 Apache Lucene[14]項目的開源企業(yè)搜索平臺,支持全文檢索、命中提示、分面搜索、動態(tài)聚類等。ES是一個實時的分布式搜索和分析引擎,可以用于全文搜索、結(jié)構(gòu)化搜索及分析,支持Lucene的近實時檢索,目前被維基百科、GitHub、StackOverflow、英國衛(wèi)報等組織和企業(yè)廣泛使用。兩者相比,Solr擁有更多的開發(fā)和貢獻者,較為成熟和穩(wěn)定,但是并不支持實時索引和搜索;ES的部署、維護更為簡單,且支持近實時搜索。
本文提出一種基于反射和注解的HBase-ORM框架,能夠應(yīng)用與多類數(shù)據(jù)的索引及檢索,所述系統(tǒng)包括Hadoop平臺層、數(shù)據(jù)訪問層、HBase-ORM層、業(yè)務(wù)邏輯層和web服務(wù)層,通過利用HBase-ORM層對上層和下層進行隔離,上層包括業(yè)務(wù)邏輯層和web服務(wù)層,下層包括Hadoop平臺層和數(shù)據(jù)訪問層。框架邏輯分層如圖1所示。
圖1 HBase-ORM框架分層示意圖
其中,Hadoop平臺層通過搭建Hadoop集群,利用HBase來作為數(shù)據(jù)庫存儲數(shù)據(jù),所述數(shù)據(jù)包括文本、數(shù)值、經(jīng)緯度和圖像數(shù)據(jù)。
數(shù)據(jù)訪問層提供HBase數(shù)據(jù)庫的數(shù)據(jù)訪問接口,根據(jù)HBase-ORM層的指定輸入,利用HBase API完成數(shù)據(jù)的增加、刪除、修改和查詢操作,為HBase-ORM層提供HBase數(shù)據(jù)庫的操作接口。
HBase-ORM層用于連接數(shù)據(jù)訪問層和業(yè)務(wù)邏輯層,通過部署ES集群來對HBase數(shù)據(jù)庫中的文本、數(shù)值和經(jīng)緯度數(shù)據(jù)建立索引,并提供查詢接口,通過部署ES圖像檢索插件,使ES集群支持對圖像數(shù)據(jù)進行索引和檢索,HBase-ORM層將調(diào)用數(shù)據(jù)訪問層完成HBase數(shù)據(jù)庫基本操作,并對業(yè)務(wù)邏輯層暴露統(tǒng)一的接口,所述基本操作包括增加、刪除、修改和查詢。
業(yè)務(wù)邏輯層用于特定業(yè)務(wù)的規(guī)則制定和業(yè)務(wù)流程實現(xiàn),業(yè)務(wù)邏輯層根據(jù)Web服務(wù)層的訪問請求,調(diào)用HBase-ORM層完成數(shù)據(jù)訪問、數(shù)據(jù)處理操作,并將數(shù)據(jù)返回給Web服務(wù)層。
Web服務(wù)層為用戶提供數(shù)據(jù)的展示,以Web方式為用戶呈現(xiàn)業(yè)務(wù)相關(guān)內(nèi)容,提供交互界面,接受用戶的訪問請求,并傳遞給業(yè)務(wù)邏輯層,同時接收業(yè)務(wù)邏輯層返回相關(guān)內(nèi)容并展示給用戶。
ES插件是ES提供的一種標(biāo)準(zhǔn)功能擴展方法。通過插件開發(fā)者可以對ES功能進行自定義擴展,比如添加新的分析器,開發(fā)現(xiàn)有功能的替代品等等?;?Lire[15~16]的 ES 圖像搜索插件就是利用ES提供的自定義插件功能開發(fā)的一套基于顏色特征的圖像快速檢索工具。在原生的ES中只提供了文本數(shù)據(jù),數(shù)值數(shù)據(jù),經(jīng)緯度數(shù)據(jù)等常規(guī)數(shù)據(jù)的快速檢索,沒有提供圖像數(shù)據(jù)的快速檢索。為了實現(xiàn)大規(guī)模圖像數(shù)據(jù)的快速檢索,本方法對Lire插件進行了擴展,通過提取圖像的顏色特征、序列特征和人臉特征作為圖像描述算子,支持圖像檢索。
HBase ORM框架主要包括兩部分:對象映射和數(shù)據(jù)訪問。其中對象映射通過利用注解來描述HTable對應(yīng)的表結(jié)構(gòu),包括表名、列族名、索引名、列名、列類型等。如圖1所示,通過HTableConf注解來描述表名、列族和索引名,通過HColumn注解來描述HTable中對應(yīng)的列名,利用HType注解來描述該列對應(yīng)的類型。
表1 列類型及索引說明
數(shù)據(jù)訪問模塊則負責(zé)進行數(shù)據(jù)的增刪改查、建立和更新索引等操作。
數(shù)據(jù)訪問層為用戶提供簡潔的數(shù)據(jù)存儲接口(增加、修改)。首先根據(jù)注解獲取數(shù)據(jù)對應(yīng)的表名、列族名、列名,從而確定數(shù)據(jù)在HBase中的存儲位置,同時還獲取了相應(yīng)的索引名,以確定數(shù)據(jù)在ES中的索引存儲位置,以及每列數(shù)據(jù)對應(yīng)的數(shù)據(jù)類型(如表1所示),針對不同數(shù)據(jù)類型,建立不同的索引。如圖2所示,表名為T_CV_CACE,列族名為basic,索引名為cvtables。
數(shù)據(jù)存儲過程中首先根據(jù)獲取的表名、列族名、列名對HBase進行操作,如果不存在相應(yīng)表、列族或列,則在HBase中新建,同時在ES中新建對應(yīng)索引,并根據(jù)每列的數(shù)據(jù)類型建立或更新索引結(jié)構(gòu)。最后將數(shù)據(jù)寫入HBase,針對非圖像數(shù)據(jù),在ES中建立倒排索引,針對圖像數(shù)據(jù),則對圖像提取特征(不同圖像類型提取不同視覺特征,具體如表1所示),并保存特征向量。
圖2 基于注解的對象映射示意圖
數(shù)據(jù)檢索時首先根據(jù)注解獲取數(shù)據(jù)對應(yīng)的表名、列族名、列名、索引名、數(shù)據(jù)類型以及數(shù)據(jù)值。然后根據(jù)對應(yīng)的索引名獲取相應(yīng)索引,對于非圖像數(shù)據(jù),可以根據(jù)輸入的數(shù)據(jù)及倒排索引獲取根據(jù)相似度排序的數(shù)據(jù)的行鍵值列表;對于圖像數(shù)據(jù),則首先對輸入圖像提取特征,并與索引中存儲的所有特征向量計算相似度,并進行排序,從而獲取相似圖像的行鍵值列表。最后根據(jù)獲取的鍵值結(jié)合表名、列族名以及列名從HBase中讀取相應(yīng)數(shù)據(jù)并返回。
系統(tǒng)進行數(shù)據(jù)刪除時執(zhí)行如下步驟:HBase-ORM層通過用戶給定的輸入查詢并返回相關(guān)數(shù)據(jù),在HBase數(shù)據(jù)庫中刪除相關(guān)行,并在ES集群中刪除相關(guān)索引。
為驗證本文HBase-ORM框架,我們基于B/S架構(gòu),參照圖1搭建了一套基于該框架的結(jié)構(gòu)化與非結(jié)構(gòu)化數(shù)據(jù)存儲與檢索系統(tǒng)?;诒疚乃鯤Base-ORM框架,實現(xiàn)了結(jié)構(gòu)化與非結(jié)構(gòu)化數(shù)據(jù)的一致化存儲與檢索,極大地簡化了基于HBase的數(shù)據(jù)存儲及檢索系統(tǒng)開發(fā)工作。系統(tǒng)支持對文本、數(shù)字、日期、經(jīng)緯度、圖像等進行相似度查詢,查詢結(jié)果如下,其中圖3展示了圖像相似度檢索結(jié)果示意圖,圖4展示了人臉圖像檢索結(jié)果示意圖。
圖3 圖像相似度檢索結(jié)果示意圖
圖4 人臉圖像檢索結(jié)果示意圖
本方法利用了Java的反射和注解機制來簡化了HBase的數(shù)據(jù)插入、修改與刪除,對上層用戶屏蔽了HBase的API,減少代碼冗余,提高數(shù)據(jù)訪問的效率及可靠性;其次結(jié)合ES在數(shù)據(jù)的插入與修改過程中根據(jù)不同的數(shù)據(jù)類型(包括文本、數(shù)值、經(jīng)緯度等)建立索引,并支持對索引數(shù)據(jù)的近實時搜索,從而提高了HBase數(shù)據(jù)訪問和檢索的效率;最后,通過對ES進行圖像檢索插件的擴展,從而使ES支持對HBase中保存的彩色圖像或人臉圖像等進行相似度檢索,在建立圖像索引之后,可以實現(xiàn)圖像的相似度搜索,從而實現(xiàn)了面向HBase的結(jié)構(gòu)化與非結(jié)構(gòu)化數(shù)據(jù)一致化索引與檢索。