吳 姍, 趙 健, 劉丹丹, 余江順, 伍思睿
(中國電建集團 貴州電力設(shè)計研究院有限公司, 貴陽 550002)
隨著社會日趨智能化,地圖逐漸進入人們的生活,而地圖與之相關(guān)的專業(yè)名詞就是興趣點(point of interest,POI)。POI 廣義可以理解為點的地理對象,主要用來對事物地址進行描述, 能較大程度上增強對事物位置的描述和查詢能力。POI 數(shù)據(jù)既包含諸如名稱、電話、經(jīng)緯度、地址等屬性數(shù)據(jù),也包含視頻、音頻等一系列非結(jié)構(gòu)化數(shù)據(jù),而且POI數(shù)據(jù)日益增長,能夠達到T-B級甚至P-B級。
對于POI的研究越來越廣泛,但并沒有很好地對 POI 進行高效管理的方式。本文旨在 POI 數(shù)據(jù)在爆炸性增長的問題上,針對海量 POI 數(shù)據(jù)存儲問題,采用混合存儲策略;針對POI數(shù)據(jù)檢索,使用關(guān)系型數(shù)據(jù)庫的檢索方案和 HBase 檢索數(shù)據(jù)的相關(guān)方法,且對 HBase 建立二級索引,同時嵌入Solr全文的搜索引擎,Solr 可實現(xiàn)全量更新與自動緩存,與 Oracle 形成互補的關(guān)系,增強 Oracle 的查詢,提高檢索效率。
通過分析,POI數(shù)據(jù)包含了名稱、類別和地址3個屬性。 POI 的名字解決了“是什么”,POI 的地址回答了“在哪里”,除此之外,由于 POI 的復雜性,還包括其他的一些屬性信息,如電話、地址編碼、描述信息等。還包括 POI 的非結(jié)構(gòu)化的數(shù)據(jù),如空間坐標、POI 點的視頻、音頻等信息[1],非結(jié)構(gòu)化的數(shù)據(jù)關(guān)系并不緊密。數(shù)據(jù)結(jié)構(gòu)對比見表1。
表1 數(shù)據(jù)結(jié)構(gòu)對比
由于每個 POI 都有屬于自己的名稱、電話、經(jīng)緯度、地址等信息,在 POI 建模時,考慮 POI 通用的數(shù)據(jù)模型,將其提取出來,方便 POI 的管理。
POI屬性數(shù)據(jù)可使用關(guān)系型數(shù)據(jù)庫 MySQL 或者 Oracle存儲。關(guān)系數(shù)據(jù)庫存儲的基本形式是數(shù)據(jù)表,每個表只能屬于一種模式,但可以被多個用戶訪問[2-3]。表中的記錄由眾多字段組成,用戶可以對某些字段定義規(guī)則,這類規(guī)則叫作完整性約束,它對于表中這個字段的所有記錄都是有效的[4-5]。
針對本文的POI屬性樣本數(shù)據(jù),在 Oracle 中建立一張通用的名為POI的表,其結(jié)構(gòu)見表2,并在關(guān)系型數(shù)據(jù)庫中建立用戶名,進行權(quán)限分配、表空間分配,最后借助Oracle操作軟件PL/SQL,將數(shù)據(jù)導入 Oracle 數(shù)據(jù)庫,完成屬性數(shù)據(jù)存儲。
表2 POI屬性表結(jié)構(gòu)
關(guān)系數(shù)據(jù)庫存儲POI數(shù)據(jù)時,信息不存在的字段會自動存為null,即便為null,仍然占用關(guān)系數(shù)據(jù)庫內(nèi)存,且增加POI字段時,需要停止服務(wù),耗時較大。而HBase對非結(jié)構(gòu)化數(shù)據(jù)處理性能遠遠高于關(guān)系型數(shù)據(jù)庫,且 HBase能動態(tài)增加列,可以很好地解決停止服務(wù)方可增加字段的缺陷。故針對POI非結(jié)構(gòu)化數(shù)據(jù),本文采用Hbase數(shù)據(jù)庫進行存儲。
1.3.1 HBase存儲POI非結(jié)構(gòu)化數(shù)據(jù)邏輯
HBase可以動態(tài)增加,可理解成一張偌大的表,列數(shù)一般可以增加到超10億列,列寬足以對動態(tài)增加的數(shù)據(jù)列進行管理,可隨時進行數(shù)據(jù)擴展,但增加的列并不是全都用來存儲數(shù)據(jù)。本文研究數(shù)據(jù)存儲時,主要是要對行鍵和列簇進行設(shè)計。表3為HBase邏輯視圖。
表3 HBase邏輯視圖
Row Key為行鍵,POI Inform 是列簇,示例數(shù)據(jù)(1001,POIInform:name,t4)和(1002,POIInform:name,t2) 分別存儲大廈和廣場 POI 所在非結(jié)構(gòu)化數(shù)據(jù),HBase 中存儲 POI 的非結(jié)構(gòu)化信息,主要通過使用二進制文件 BLOB。
1.3.2 Hbase存儲POI非結(jié)構(gòu)化數(shù)據(jù)策略
二進制文件主要是對數(shù)據(jù)類型為blob的文件進行存儲。POI的blob文件主要有對象名字、大小、類型、內(nèi)容等字段。如果對應(yīng)的存儲文件較小,則可以直接將內(nèi)容存儲在HBase中,如果內(nèi)容較大,需考慮存儲文件的所在路徑,HBase通過尋找路徑來對路徑對應(yīng)的數(shù)據(jù)進行存儲。
以非結(jié)構(gòu)化數(shù)據(jù)(圖片)存儲為例,首先在 HBase 里新建一張大表,用一個單獨的列簇存儲 POI 的圖片內(nèi)容,其他列簇存儲圖片信息的大小、名稱、類型等其他信息,結(jié)構(gòu)見表4,圖片內(nèi)容與名稱、大小等不屬于同一屬性,這樣存儲可以幫助圖片的多屬性查詢操作。Hbase列簇的動態(tài)增加,可以進行擴展,進而存儲圖片的更多信息,能實現(xiàn)圖片相關(guān)信息的擴展查詢效果。
表4 Hbase的POI圖片存儲
使用HBase對POI圖片存儲具有以下優(yōu)點:①滿足HBase的列簇設(shè)計要求,能夠較好地進行列簇的設(shè)計,即將圖片內(nèi)容存在一個列簇,將圖片大小、內(nèi)容等信息保存在另外一個列簇,而圖片的內(nèi)容跟大小、名稱等不屬于同一屬性,這樣存儲能夠幫助圖片的多屬性查詢操作;②HBase 列簇能夠動態(tài)增加,可以對列簇擴展,來保存跟圖片相關(guān)的信息,能夠達到對圖片相關(guān)消息的擴展查詢的效果。
采用關(guān)系型數(shù)據(jù)庫Oracle和分布式數(shù)據(jù)庫HBase這種混合存儲策略實現(xiàn)POI的結(jié)構(gòu)化屬性數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)交互,在實際應(yīng)用中需進行交互,本文采用Sqoop實現(xiàn)交互操作,交互架構(gòu)如圖1所示。
圖1 Sqoop交互架構(gòu)
客戶端發(fā)送請求到Sqoop,Sqoop通過Java代碼調(diào)用與請求相關(guān)的API[6-7],通過任務(wù)轉(zhuǎn)換器,將請求發(fā)送到Hadoop框架,并將任務(wù)轉(zhuǎn)換成mapreduce命令,通過mapreduce將關(guān)系數(shù)據(jù)庫和HBase數(shù)據(jù)庫的信息進行交互。
HBase數(shù)據(jù)檢索是在數(shù)據(jù)的存儲塊region所對應(yīng)的regionserver下完成,用戶發(fā)出搜索命令到regionserver,regionserver找到對應(yīng)的region,即找到用戶查找的存儲信息,這是HBase進行數(shù)據(jù)檢索的核心。而檢索到regionserver,需對HBase中的-ROOT- 和.META 兩張核心表進行研究,其檢索策略如圖2所示。
META.:記錄用戶表的存儲塊的信息,它有多個存儲塊,以及存儲塊所對應(yīng)的 RegionServer 的服務(wù)器地址;-ROOT-:記錄.META.表的存儲塊信息。圖2 Hbase檢索策略
從圖1中的表-ROOT-和.META.能在 HBase 中發(fā)現(xiàn)用戶進行數(shù)據(jù)訪問的核心流程。首先用戶訪問 zookpeer 協(xié)調(diào)服務(wù),協(xié)調(diào)服務(wù)接收請求后去訪問-ROOT-,得到-ROOT-的數(shù)據(jù)之后,再對.META. 表進行訪問,最后通過訪問-ROOT-和.META.表數(shù)據(jù),才能檢索到用戶需要的數(shù)據(jù), 找到該數(shù)據(jù)所對應(yīng)的用戶表[8]。-ROOT-和.META.表結(jié)構(gòu)見表5。
表5 -ROOT-和.META.表結(jié)構(gòu)
在表5中,行鍵rowkey包含表名、startkey和時間戳,3部分用逗號隔開,可表示為tablename,starkey,timestamp;列簇family:info包含基本列regioninfor、sever、severcode,其中regioninfor是存儲塊的基本信息,包括startkey、endkey和每個family的信息[9-10],Sever存儲塊對 應(yīng) 的 RegionServer 地址,故存儲信息區(qū)域操作即是對這兩張表操作。用POI樣本數(shù)據(jù)進行實驗,先構(gòu)建.META.表和-ROOT-表,表結(jié)構(gòu)分別見表6和表7。
表6 Hbase存儲POI之.META.結(jié)構(gòu)
表7 Hbase存儲POI之-ROOT-表結(jié)構(gòu)
針對表6,假設(shè)HBase中僅有table1和table2,table1較大,分成很多存儲塊,在.META.表中有需使用很多行來記錄信息。而table2 較小,僅被分成兩個存儲塊,因此在.META.中只有兩行用來存儲信息。若從table1里面查詢一條rowkey=PK3000的數(shù)據(jù),需遵循如下步驟:①從.META里面查詢包含PK3000的存儲塊;②獲取存儲塊的服務(wù)地址;③連接服務(wù)地址,獲取數(shù)據(jù)[11-12]。
針對表7,同樣假設(shè)Hbase只有兩種表table1和table2,由于-ROOT-是記錄.META.的信息,其結(jié)構(gòu)設(shè)計為表6。假設(shè)在table1里查找rowkey=PK3000的數(shù)據(jù),需要進行遞歸調(diào)用:獲取table1中行鍵為RK30000 的存儲塊所對應(yīng)的服務(wù)=>獲取.META.表,行鍵為table1 RK3000,t1 的存儲塊所對應(yīng)的服務(wù)=>獲取-ROOT-,行鍵為 table1 RK3000,t1,t2 的存儲塊所對應(yīng)的服務(wù)=>ZooKeeper 得到-ROOT-的存儲塊所對應(yīng)的服務(wù),并查找行鍵為.META.,table1,RK3000 的一條Row,得到.META.的存儲塊所對應(yīng)的服務(wù) =>從.META.表中查到行鍵為table1的RK3000的存儲塊,得到table1存儲塊所對應(yīng)的服務(wù)=>從table1中查到RK3000的存儲記錄,即得到結(jié)果。
為實現(xiàn)POI數(shù)據(jù)的準確快速檢索,本文使用Solr進行優(yōu)化,同時針對非結(jié)構(gòu)化數(shù)據(jù)的檢索創(chuàng)建二級索引實現(xiàn)優(yōu)化。Solr可定義接口,實現(xiàn)全量更新和增量更新,且Solr自帶緩存功能,在服務(wù)器存儲經(jīng)常搜索的POI,下一次觸發(fā)時,無須再進入數(shù)據(jù)庫查詢,其次,Solr是基于Lucene操作的,檢索效率較高。因本文POI存儲涉及到關(guān)系型數(shù)據(jù)庫Oracle和分布式數(shù)據(jù)庫Hbase,需分別對兩者創(chuàng)建索引。
2.2.1 關(guān)系型數(shù)據(jù)庫索引創(chuàng)建
本文研究的POI數(shù)據(jù)除經(jīng)緯度坐標之外,其他均為屬性信息,因此對于樣本數(shù)據(jù)可以考慮使用 Solr 對 Oracle數(shù)據(jù)庫建立索引。使用 Solr 相關(guān)文件配置,將保存在 Oracle 的數(shù)據(jù)庫導入 Solr ,完 成 POI 全文索引的創(chuàng)建,然后使用 Java 語言,查詢 Solr 中的數(shù)據(jù)庫。
2.2.2 非結(jié)構(gòu)化數(shù)據(jù)索引創(chuàng)建
針對單條件搜索,只需使用行鍵rowkey進行即可,較為簡單,本文主要針對多條件搜索進行優(yōu)化。Hbase數(shù)據(jù)庫能同時存儲POI的非結(jié)構(gòu)化數(shù)據(jù)和屬性數(shù)據(jù),針對多條件搜索,需建立二級索引。因此使用HBase自帶的協(xié)處理器生成索引,基于 Redis 的 HBase 的二級索引的設(shè)計,通過協(xié)處理器,將索引存為一張表[13-14]。
2.2.2.1 基于Redis的HBase的二級索引
該二級索引結(jié)構(gòu)主要包括數(shù)據(jù)處理、二級索引和客戶端三大模塊。當用戶發(fā)出數(shù)據(jù)的增刪改查操作時,HBase 數(shù)據(jù)處理模塊接受用戶請求,分別對請求進行處理,同樣,二級索引模塊根據(jù)客戶端請求進行二級索引的增刪改查?;?Redis 實現(xiàn) HBase 二級索引,協(xié)處理器相當于一個回調(diào)函數(shù),協(xié)處理器通過配置可以實現(xiàn)作用到 HBase 中所有表,也可以單獨指定作用到一張表。當用戶操作 get/put/delete 數(shù)據(jù)時,HBase 中的regionserver 會在 get/put/delete回調(diào)一個實現(xiàn)協(xié)處理器類中的方法,方法中可以獲得 get/put/delete 的數(shù)據(jù),從而實現(xiàn)構(gòu)建二級索引的操作[15]。
2.2.2.2 HBase二級索引數(shù)據(jù)結(jié)構(gòu)研究
POI多條件搜索,即POI 非 rowke搜索,包括 POI 精確查詢和范圍查詢,通過Redis set 和 sorted set 實現(xiàn)二級索引的創(chuàng)建,以達到較高的搜索效率。以該索引創(chuàng)建思路,以表8 POI樣本數(shù)據(jù)為例,對 POI 的 tel 創(chuàng)建索引。
表8 POI樣本數(shù)據(jù)
POI精確查詢,使用 Redis的set 類型建立二級索引,結(jié)構(gòu)為key-value,key 為列名_值,value 為 rowkey,為(key,value)添加二級索引。生成的二級索引見表9。
表9 Redis中的set建立二級索引
POI范圍查詢,使用 Redis 的 sorted set 類型進行建立二級索引,結(jié)構(gòu)為 key-score-value,key為列名,score 為列值,value 為列值_rowkey。為(key,score, value)添加二級索引。生成的二級索引,見表10。
表10 Redis中的sorted set建立二級索引
2.2.2.3 HBase 二級索引優(yōu)化實驗
在HBase和Redis 系統(tǒng)、 JDK1.7.0_55、Hadoop 1.1.2、HBase 0.96.2、Redis 3.2.1的實驗環(huán)境下,對POI樣本數(shù)據(jù)建立Hbase二級索引,用Hbase系統(tǒng)查詢POI數(shù)據(jù),使用查詢語句對Hbase查詢進行性能測試,結(jié)果見表11。
表11 Hbase二級索引測試結(jié)果
根據(jù)測試結(jié)果可知,在實現(xiàn)二級索引的情況下,HBase 查詢性能極大提升。 這是因為 HBase 在執(zhí)行基于 rowkey 的查詢時,查詢速率很高,而在建立二級索引的情況,系統(tǒng)會將對非 rowkey 的查詢,通過查詢 Redis 中的二級索引獲得符合條件的 rowkey,再通 rowkey 在 HBase 中獲得數(shù)據(jù)集,間接地將基于非 rowkey 的查詢轉(zhuǎn)化為基于 rowkey 的查詢,獲得較高的查詢效率。
通過建立二級索引可以明顯提升檢索效率,同時在POI 搜索引擎上,嵌入 Solr 的全文的搜索引擎,增強檢索優(yōu)勢。Solr 可實現(xiàn)全量更新,與Oracle形成互補關(guān)系。把數(shù)據(jù)導入到 Solr ,比如將多個表的數(shù)據(jù)全部導入Solr,由于 Solr 被理解成一張很大的表,故多個表的數(shù)據(jù)相當于保存在一張表,一張表建立索引,查詢數(shù)據(jù)效率就會高很多;且Solr自帶緩存功能,某些POI被搜索的頻率較高,Solr會自動將這些數(shù)據(jù)進行緩存,當用戶對該POI二次搜索時,可直接從緩存庫中將搜索結(jié)果展現(xiàn)出來,不再需要對數(shù)據(jù)庫進行遍歷,從而提升檢索效率,且Solr 索引和全文搜索可以實現(xiàn)更多的搜索功能,增強Oracle的查詢。
Solr增量導入 Oracle 數(shù)據(jù)技術(shù),首先需要配置數(shù)據(jù)結(jié)構(gòu)配置文件schema.xml、數(shù)據(jù)庫配置文件 oracle-poi.xml和數(shù)據(jù)庫實體配置文件 solrconfig.xml,然后進行 dataimport 操作,將 oracle 數(shù)據(jù)導入 Solr 中。通過 java 調(diào)用 solr 接口,將保存在 oracle 的 POI 樣本數(shù)據(jù)保存在服務(wù)器上,來完成 POI 的搜索功能。在搜索引擎中對POI非結(jié)構(gòu)化數(shù)據(jù)檢索,主要代碼實現(xiàn)類如圖3所示。
圖3 POI操作類圖
本文采用1 000~100 000個POI非結(jié)構(gòu)化文件測試數(shù)據(jù),文件大小從20.5 G到3 T,數(shù)據(jù)大小見表12。
表12 POI非結(jié)構(gòu)化數(shù)據(jù)測試數(shù)據(jù)大小
將其 POI 信息分別存儲在 Oracle 集群中和 HBase 分布式數(shù)據(jù)庫中,然后輸入相同的搜索條件,進行 POI 搜索,得到具體搜索條件見表13。
表13 檢索POI非結(jié)構(gòu)化數(shù)據(jù)時間對比
在 POI 數(shù)據(jù)量不大的情況下,采用關(guān)系型數(shù)據(jù)庫與分布式數(shù)據(jù)庫 HBase 進行數(shù)據(jù)檢索差別不大,查詢時間在同一量級上。但是隨著POI 數(shù)據(jù)量的增多,采用 HBase 進行 POI 非結(jié)構(gòu)化數(shù)據(jù)查詢時,檢索效率明顯比關(guān)系型數(shù)據(jù)庫快得多,為直觀對比,制作折線圖(圖4)。經(jīng)過實驗驗證,可以得到使用 HBase 進行 POI 非結(jié)構(gòu)化數(shù)據(jù)的存儲管理的方法是可行的且是正確高效的。
圖4 Oracle與HBase檢索耗時對比
通過研究 POI 數(shù)據(jù)特點,建立 POI 數(shù)據(jù)模型,提出 POI結(jié)構(gòu)化屬性數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)的混合存儲策略;針對不同的存儲方式,采用關(guān)系型數(shù)據(jù)庫和 HBase 檢索數(shù)據(jù)的方法,對 HBase 建立二級索引,得出建立二級索引的優(yōu)點。最后嵌入Solr的全文搜索引擎,使“全量更新”與 Oracle 形成互補的關(guān)系;Solr索引和全文搜索可以實現(xiàn)更多的搜索功能,增強 Oracle 的查詢。實驗結(jié)果表明,在使用本文的存儲和檢索方案之后,對POI數(shù)據(jù)的檢索效率有所提高。