楊旭明, 李 忠, 李錦文, 賈 娟, 楊百一, 張富志
(防災(zāi)科技學(xué)院 應(yīng)急管理學(xué)院, 河北 三河 065201)
張衡一號衛(wèi)星從2018 年在軌至今,其搭載的載荷觀測數(shù)據(jù)量已達(dá)幾百TB,各個(gè)載荷觀測數(shù)據(jù)會(huì)經(jīng)過一系列的處理、流程以及相應(yīng)的算法進(jìn)行存儲和科學(xué)研究,會(huì)涉及針對海量數(shù)據(jù)的存儲、訪問以及入庫方面的不同需求。
HBase 是一個(gè)分布式的、面向列的開源數(shù)據(jù)庫,可以隨機(jī)的、實(shí)時(shí)的訪問大數(shù)據(jù)。 HBase 具有高性能、高可靠性、列存儲、可伸縮、實(shí)時(shí)讀寫等特性,可以滿足張衡一號衛(wèi)星海量數(shù)據(jù)的高效存儲與讀取需求,但是怎樣有效的將衛(wèi)星海量數(shù)據(jù)導(dǎo)入到HBase 數(shù)據(jù)庫是當(dāng)前迫切需要解決的問題。HBase 有多種導(dǎo)入數(shù)據(jù)的方法,最直接的方法就是調(diào)用HBase 的API,用Put 方法插入數(shù)據(jù);另外一種是通過MapReduce 編程模型的函數(shù)從分布式文件系統(tǒng)(HDFS)中加載數(shù)據(jù),再通過其函數(shù)直接生成Put 對象后寫入HBase。 但是這兩種方法都是使用了較為傳統(tǒng)的Put 方法來存儲數(shù)據(jù),十分耗時(shí),同時(shí)也沒有合理利用軟硬件,會(huì)讓HBase頻繁地進(jìn)行刷寫(Flush)、合并(Compact)、拆分(Split)等操作,因此需要消耗較大的CPU 和網(wǎng)絡(luò)資源,會(huì)導(dǎo)致HBase 集群中運(yùn)行HRegionServer 服務(wù)從節(jié)點(diǎn)服務(wù)器(Region Server)的壓力非常大。 而Bulk Load 方式則無需進(jìn)行刷寫、合并、拆分等過程,不占用HBase 的分片存儲單元(Region)資源,也不會(huì)產(chǎn)生巨量的寫入操作,只需要較少的CPU 和網(wǎng)絡(luò)資源,就能極大的提高寫入效率,并降低對Region Server 節(jié)點(diǎn)的寫入壓力。 張衡一號衛(wèi)星海量空間電場數(shù)據(jù)入庫時(shí),Bulk Load 則為其提供了一種全新有效的方法。
HBase 物理存儲模型,如圖1 所示。 HBase 中主節(jié)點(diǎn)(Master)上運(yùn)行Hmaster 服務(wù),其作用是維護(hù)整個(gè)集群的負(fù)載均衡、為Region Server 節(jié)點(diǎn)分配Region、維護(hù)集群的元數(shù)據(jù)信息等;Region Server 節(jié)點(diǎn)上運(yùn)行HRegionServer 程序,其作用是管理一系列的Region、處理來自客戶端的讀寫請求等。 每個(gè)Region 又由多個(gè)HBase 存儲基本單元(Store)構(gòu)成,每個(gè)Store 與HBase 的列族是一一對應(yīng)的;Store 由內(nèi)存存儲(MemStore)和存儲文件(StoreFile)組成,MemStore 是寫緩存,當(dāng)其大小達(dá)到特定閾值后就會(huì)觸發(fā)刷寫操作生成存儲文件(StoreFile),每個(gè)StoreFile 會(huì)以HBase 的物理文件(HFile)格式存儲在HDFS 中。
圖1 HBase 物理存儲模型Fig.1 HBase physical storage model
客戶端的插入數(shù)據(jù)操作其實(shí)就是遠(yuǎn)程過程調(diào)用協(xié)議(RPC)請求,當(dāng)數(shù)據(jù)到達(dá)Region Server 時(shí),會(huì)被默認(rèn)先寫入到預(yù)寫日志(Write Ahead Log,以下簡稱WAL)即HLog 中;再將數(shù)據(jù)寫入到相應(yīng)Region 的MemStore 中,當(dāng)達(dá)到MemStore 的特定閾值之后,觸發(fā)刷寫(Flush) 操作,將數(shù)據(jù)刷新到StoreFile,StoreFile 則以HFile 格式存到HDFS 中,此時(shí)的Flush 操作引起的寫操作會(huì)瞬間堵塞用戶。 當(dāng)StoreFile 數(shù)量達(dá)到特定的閾值時(shí),會(huì)觸發(fā)Compact操作,多個(gè)StoreFile 會(huì)被合并為一個(gè)大的StoreFile,該過程包含了大量的網(wǎng)絡(luò)和硬盤I/O。 當(dāng)StoreFile過大并達(dá)到相應(yīng)閾值后又會(huì)被Split 操作拆分。HBase 客戶端API 寫入數(shù)據(jù)的原理圖,如圖2 所示。 從通過HBase API 方法寫入數(shù)據(jù)的流程可知,客戶端在Put 數(shù)據(jù)時(shí),需要頻繁的與存儲數(shù)據(jù)的Region Server 通信,當(dāng)一次寫入大量數(shù)據(jù)時(shí),就會(huì)占用Region Server 的大量資源,就會(huì)大大影響對該Region Server 上存儲表的操作。 因此,當(dāng)大批量數(shù)據(jù)寫入時(shí),會(huì)導(dǎo)致效率極其低下,從而影響HBase集群節(jié)點(diǎn)的穩(wěn)定性。
圖2 HBase API 寫入數(shù)據(jù)原理圖Fig.2 HBase API data writing schematic diagram
通過HBase 物理存儲模型的原理可知,HBase數(shù)據(jù)是以HFile 文件結(jié)構(gòu)在HDFS 中存儲的。 因此,可以先將數(shù)據(jù)生成HFile 結(jié)構(gòu)文件,再把生成的HFile 文件加載到HBase 中。 Bulk Load 批量加載方法的原理就是通過使用MapReduce 作業(yè)以HBase內(nèi)部數(shù)據(jù)格式輸出表數(shù)據(jù),直接將生成的StoreFiles加載到正在運(yùn)行的集群中,從而快速完成海量數(shù)據(jù)的入庫,該過程繞過了Put 操作中寫數(shù)據(jù)的路徑包括WAL、MemStore、Flush 等,不會(huì)占用Region 資源,也不會(huì)產(chǎn)生大量的寫入I/O,因此使用Bulk Load 比通過HBase API 加載占用更少的CPU 和網(wǎng)絡(luò)資源。
利用Bulk Load 進(jìn)行HBase 批量數(shù)據(jù)加載的過程主要分為兩個(gè)步驟:使用MapReduce Job 準(zhǔn)備數(shù)據(jù)和完成數(shù)據(jù)加載。 Bulk Load 方法加載數(shù)據(jù)過程如圖3 所示。
圖3 Bulk Load 方法加載數(shù)據(jù)過程Fig.3 The process of data loading of Bulk Load method
1.3.1 使用MapReduce 生成數(shù)據(jù)
Bulk Load 批量加載的第一步是使用官方提供的ImportTSV 工具將HDFS 中TSV 格式數(shù)據(jù)轉(zhuǎn)化為HBase 數(shù)據(jù)文件HFile,或者使用相應(yīng)的類編寫MapReduce 作業(yè)程序生成HFile。 這種輸出格式以HBase 的內(nèi)部存儲格式寫出數(shù)據(jù),以便后續(xù)可以高效地將數(shù)據(jù)加載到集群中。
ImportTSV 工具適用于很多實(shí)際情況,但是需要手動(dòng)指定所有的列名,在面對需要導(dǎo)入的數(shù)據(jù)中存在很多列名的情況時(shí),該方法顯得尤為笨重。 因此很多情況下高需求用戶會(huì)通過編寫MapReduce 作業(yè)生成數(shù)據(jù)。
1.3.2 完成數(shù)據(jù)加載
將MapReduce 生成的目標(biāo)數(shù)據(jù)文件加載到HBase 中。 此工具通過遍歷準(zhǔn)備好的HFile 數(shù)據(jù)文件,確定每個(gè)文件所屬的Region,通過相應(yīng)的Region Server 將HFile 數(shù)據(jù)文件加載到存儲目錄。 如果在整個(gè)過程中的某個(gè)階段Region 邊界發(fā)生改變,則將HFile 數(shù)據(jù)文件自動(dòng)拆分為和Region 新邊界對應(yīng)的部分。
本文以張衡一號監(jiān)測衛(wèi)星空間電場數(shù)據(jù)中的ULF 頻段數(shù)據(jù)作為數(shù)據(jù)來源。 張衡一號衛(wèi)星空間電場數(shù)據(jù)現(xiàn)有的存儲方式為H5 格式文件,每個(gè)文件包括波形數(shù)據(jù)和功率譜數(shù)據(jù),單個(gè)文件數(shù)據(jù)量大,嚴(yán)重制約了數(shù)據(jù)的存儲、訪問、查詢等效率,為此選擇HBase 數(shù)據(jù)庫作為存儲數(shù)據(jù)庫。 由于數(shù)據(jù)涉及衛(wèi)星編號、軌道號、工作模式、時(shí)間、地理經(jīng)度、地理緯度、地磁經(jīng)度、地磁高度、頻率等等很多的字段,因此選擇使用HBase API 方法和編寫MapReduce 作業(yè)的Bulk Load 方法進(jìn)行入庫實(shí)驗(yàn)對比。
為對比兩種HBase 入庫方法在實(shí)際生產(chǎn)環(huán)境中的效果,本文使用Docker 容器技術(shù)搭建了由5 臺服務(wù)器節(jié)點(diǎn)組成Hadoop 高可用集群,每個(gè)節(jié)點(diǎn)的硬件配置為4 核CPU、16 G 內(nèi)存和300 G 硬盤。 每個(gè)節(jié)點(diǎn)安裝Centos7 操作系統(tǒng)和JDK1.8 環(huán)境,并按照表1中的角色分配情況在相應(yīng)節(jié)點(diǎn)上安裝Hadoop3.2.2、ZooKeeper3.6.2 和HBase2.2.7 軟件。 測試數(shù)據(jù)選用張衡一號衛(wèi)星2018 年8 月1 日中的部分空間電場ULF 頻段數(shù)據(jù)。 開發(fā)語言選擇Java 語言和Python 語言。
表1 Hadoop 集群角色分配Tab.1 Hadoop Cluster role assignment
表1 中ZooKeeper 是分布式應(yīng)用程序協(xié)調(diào)服務(wù),通過其簡單的架構(gòu),在分布式環(huán)境中協(xié)調(diào)和管理服務(wù),是Hadoop 和HBase 的重要組件;NameNode 是HDFS 的名稱節(jié)點(diǎn),主要用來保存HDFS 的元數(shù)據(jù)信息,維護(hù)著文件系統(tǒng)樹及整棵樹內(nèi)所有的文件和目錄以及接收用戶的操作請求;DataNode 是HDFS的數(shù)據(jù)節(jié)點(diǎn),提供真實(shí)文件數(shù)據(jù)的存儲服務(wù);ZKFC 是Zoo Keeper Failover Controller 的簡寫,是ZooKeeper中一個(gè)新的組件,監(jiān)視和管理NameNode 的狀態(tài);ResourceManager 是資源管理程序,負(fù)責(zé)集群中所有資源的統(tǒng)一管理和分配,接收來自各個(gè)節(jié)點(diǎn)的資源匯報(bào)信息,并把這些信息按照一定的策略分配給各個(gè)應(yīng)用程序;NodeManager 是節(jié)點(diǎn)管理程序,用來管理Hadoop 集群中單個(gè)計(jì)算節(jié)點(diǎn);JobHistory 是歷史服務(wù)器程序,可以通過其查看已經(jīng)運(yùn)行完的MapReduce 作業(yè)記錄。
張衡一號衛(wèi)星空間電場數(shù)據(jù)目前的存儲格式為H5 格式文件,因此本文先將數(shù)據(jù)從H5 文件中提取出來,進(jìn)行轉(zhuǎn)換生成制表格式的txt 文件,為后續(xù)的數(shù)據(jù)入庫操作做準(zhǔn)備。 具體對比實(shí)驗(yàn)流程如圖4 所示。
圖4 對比實(shí)驗(yàn)流程Fig.4 Flow chart of comparative experiment
(1)數(shù)據(jù)轉(zhuǎn)換步驟。 本實(shí)驗(yàn)通過Python 語言進(jìn)行編程。 首先,反轉(zhuǎn)H5 文件中的時(shí)間字段數(shù)據(jù)作為HBase 的行鍵前綴;再通過讀取H5 文件名稱和內(nèi)容中的衛(wèi)星編號、載荷編碼、載荷序號、數(shù)據(jù)分級編碼、觀測對象編碼、接收站編碼、版本號按順序組合成完整的行鍵;最后,讀取H5 文件中的字段和數(shù)據(jù),組合為字段:數(shù)據(jù)的樣式,并把行鍵、字段,數(shù)據(jù)按照制表符分隔的形式寫入到txt 文件中,實(shí)現(xiàn)從H5 格式文件到txt 文件的數(shù)據(jù)轉(zhuǎn)換。
(2)HBase API 入庫實(shí)驗(yàn)。 使用Python 語言編寫通過HBase API 的入庫程序,該方法比較簡單,只需要通過連接HBase 數(shù)據(jù)庫,讀取txt 文件中的相應(yīng)字段后存入HBase 數(shù)據(jù)庫的表中。
(3)MapReduce Bulk Load 方法入庫實(shí)驗(yàn)。 先將txt 文件上傳到HDFS 中的相應(yīng)HBase 目錄下,再使用Java 開放語言編寫自定義的MapReduce 程序?qū)?shù)據(jù)進(jìn)行讀入與拆分操作,生成HFile 文件,最后把生成的HFile 文件數(shù)據(jù)加載到HBase 中。
本實(shí)驗(yàn)分別通過HBase API 和MapReduce Bulk Load 兩種方法,執(zhí)行100、500、1 000、10 000、100 000條數(shù)據(jù)的入庫操作,統(tǒng)計(jì)每次入庫所需時(shí)間進(jìn)行對比分析,實(shí)驗(yàn)結(jié)果對比如圖5 所示。 可以看出,當(dāng)插入小于500 條的較少數(shù)據(jù)量時(shí),HBase API方法的Put 方式耗時(shí)小于MapReduce Bulk Load 方式,略有優(yōu)勢;但是隨著數(shù)據(jù)量的成倍增大,HBase API 方法的耗時(shí)顯著增加,而MapReduce Bulk Load方式的耗時(shí)雖略有增長,卻微乎其微,表明當(dāng)大批量數(shù)據(jù)需要一次性寫入HBase 數(shù)據(jù)庫時(shí),MapReduce Bulk Load 方式的優(yōu)勢是非常明顯的。
圖5 HBase 入庫方法對比圖Fig.5 Comparison diagram of HBase database entry methods
本文研究分析HBase 數(shù)據(jù)庫的入庫方法、原理,使用張衡一號衛(wèi)星空間電場ULF 頻段數(shù)據(jù)作為數(shù)據(jù)源,利用HBase API 和MapReduce Bulk Load 兩種方法進(jìn)行了不同數(shù)據(jù)量的入庫實(shí)驗(yàn)。 實(shí)驗(yàn)結(jié)果表明,當(dāng)面對少量衛(wèi)星數(shù)據(jù)入庫需求時(shí),可以選擇HBase API 的方式進(jìn)行數(shù)據(jù)插入,這種方式簡單有效,不需要編寫復(fù)雜的程序;當(dāng)面對大批量數(shù)據(jù)入庫需求時(shí),還是非常有必要選擇編寫MapReduce 程序使用Bulk Load 方式進(jìn)行高效的入庫操作。 總之,HBase 的MapReduce Bulk Load 入庫方法,為張衡一號衛(wèi)星的海量數(shù)據(jù)入庫需求提供了解決方案,為后續(xù)基于HBase 的大數(shù)據(jù)存儲方案的設(shè)計(jì)奠定了基礎(chǔ),同時(shí)為科研人員利用衛(wèi)星數(shù)據(jù)進(jìn)行的科研分析工作提供了有效的技術(shù)支撐。