一種非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中同步數(shù)據(jù)的方法【
技術(shù)領(lǐng)域:
】[0001]本發(fā)明涉及一種非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中同步數(shù)據(jù)的方法,尤其涉及非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)內(nèi)以捕獲主數(shù)據(jù)庫HBase的數(shù)據(jù)變更事件完成存儲組件之間數(shù)據(jù)同步的方法?!?br>背景技術(shù):
】[0002]多存儲系統(tǒng)是建立在數(shù)據(jù)倉庫中以多個不同類型的存儲組件共同對外提供服務(wù)的綜合數(shù)據(jù)管理系統(tǒng)。整個系統(tǒng)共用一個服務(wù)數(shù)據(jù)集,其中數(shù)據(jù)除在主存儲數(shù)據(jù)庫中儲存外,還會根據(jù)應(yīng)用的服務(wù)需要以不同的格式冗余存儲在其它存儲組件之中。相比單一的傳統(tǒng)關(guān)系型數(shù)據(jù)庫或者NoSQL數(shù)據(jù)庫,非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)不僅在存儲能力上具有強容錯、高可用和可擴展等特性,并且其可以利用不同類型的存儲組件展示一個數(shù)據(jù)集的多種服務(wù)視圖來提供更豐富的數(shù)據(jù)服務(wù)。[0003]在非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)內(nèi),主數(shù)據(jù)庫與其它數(shù)據(jù)存儲組件分布在不同的網(wǎng)絡(luò)節(jié)點中,并以網(wǎng)絡(luò)鏈路相連。需要同步的數(shù)據(jù)以字節(jié)流的形式在數(shù)據(jù)鏈路中傳輸。由于非結(jié)構(gòu)化數(shù)據(jù)海量異構(gòu)的自然屬性,它們之間的數(shù)據(jù)同步過程必須符合如下幾個條件:高效性,數(shù)據(jù)同步組件以較高的吞吐量完成數(shù)據(jù)的傳輸;時效性,數(shù)據(jù)必須以一個較小的延時在存儲組件之間同步;可擴展性,數(shù)據(jù)同步組件必須在系統(tǒng)數(shù)據(jù)量增大時提供有效的水平擴展手段。[0004]在傳統(tǒng)的非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中,數(shù)據(jù)的同步過程常由客戶端多路寫與定時數(shù)據(jù)迀移來完成。客戶端多路寫(User-drivenDualWrites)即用戶層應(yīng)用程序在向主存儲數(shù)據(jù)庫發(fā)起操作時,主動地向冗余存儲該數(shù)據(jù)的其它存儲組件發(fā)起相同的操作,從而完成數(shù)據(jù)在不同存儲組件之間的同步。定時數(shù)據(jù)迀移,即利用ETL(Extract-Transform-Load)工具周期性地按照外圍組件的數(shù)據(jù)組織要求批量地將數(shù)據(jù)加載到外圍存儲組件當(dāng)中,而無需用戶手動編寫相關(guān)功能邏輯代碼。[0005]傳統(tǒng)的數(shù)據(jù)同步方式具有如下缺點:[0006]1、客戶端多路寫雖然實現(xiàn)起來較為簡單,對系統(tǒng)自身的要求較低。但其需要應(yīng)用層程序員的參與,對系統(tǒng)組織結(jié)構(gòu)的變化敏感,任何系統(tǒng)的變動均要求應(yīng)用層程序員進行相應(yīng)的改動。并且在多路寫過程中將會引入新的一致性問題,常需要額外的協(xié)調(diào)手段對該數(shù)據(jù)同步過程進行協(xié)調(diào)。[0007]2、ETL定時迀移非實時同步的特點增加了數(shù)據(jù)更新在外圍組件中的可見延遲,實時性不強。并且其在通過主數(shù)據(jù)庫讀取其中數(shù)據(jù)時造成的負載也降低了主存儲數(shù)據(jù)庫對外提供服務(wù)的能力。[0008]DataBus是由Linkedin開源的成熟數(shù)據(jù)同步產(chǎn)品,其以快照加增量的方式提供數(shù)據(jù)同步功能。但其主要考慮的是以常見的結(jié)構(gòu)化數(shù)據(jù)庫MySQL、Oracle為主存儲數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng),現(xiàn)有的技術(shù)并沒有充分考慮在海量非結(jié)構(gòu)化數(shù)據(jù)應(yīng)用場景中,數(shù)據(jù)由NoSQL數(shù)據(jù)向其他存儲組件的同步。因此需要一種從NoSQL數(shù)據(jù)庫HBase中捕獲數(shù)據(jù)變更的方法,并以此為基礎(chǔ)實現(xiàn)DataBus的一類適宜于非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中數(shù)據(jù)同步的擴展?!?br/>發(fā)明內(nèi)容】[0009]本發(fā)明的目的在于針對目前非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中高效數(shù)據(jù)同步方式的欠缺,提出一種在以HBase為主存儲數(shù)據(jù)庫的非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中基于HBase數(shù)據(jù)變更捕獲和DataBus開源框架的數(shù)據(jù)同步方法,本發(fā)明為當(dāng)前以HBase為主存儲器的非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)提供高可用、可擴展、強容錯的數(shù)據(jù)同步手段。[0010]本發(fā)明的目的是通過以下技術(shù)方案來實現(xiàn)的:一種非結(jié)構(gòu)化數(shù)據(jù)多存儲系統(tǒng)中同步數(shù)據(jù)的方法,包括以下步驟:[0011](1)定義HBase數(shù)據(jù)變更事件統(tǒng)一模型,所述的HBase數(shù)據(jù)變更事件統(tǒng)一模型如下:[0012]Event=(TableName,TimeStamp,RowKey,ColumnFamily,Column,Value,Type),[0013]其中TableName表示數(shù)據(jù)變更發(fā)生的數(shù)據(jù)表表名;TimeStamp表示數(shù)據(jù)變更發(fā)生時的時間;RowKey表示發(fā)生數(shù)據(jù)變更數(shù)據(jù)行的行鍵值,由一個Byte序列構(gòu)成;ColumnFamily和Column表示變更發(fā)生的數(shù)據(jù)單元的列族名和列名,由一個Byte序列構(gòu)成;Type為變更的類型,用一個字節(jié)表示;Value表示數(shù)據(jù)變更的值,由Byte序列表示更新的值;[0014](2)對于原數(shù)據(jù)表中數(shù)據(jù)低于整個集群數(shù)據(jù)量20%的情況,創(chuàng)建第一類數(shù)據(jù)變更捕獲器;對于需要捕獲刪除事件或者原數(shù)據(jù)表中數(shù)據(jù)變化頻率高于2.5s每次的應(yīng)用場景,創(chuàng)建第二類數(shù)據(jù)變更捕獲器;兩類數(shù)據(jù)變更捕獲器的創(chuàng)建具體如下:[0015](2.1)創(chuàng)建第一類數(shù)據(jù)變更捕獲器,該步驟包括以下子步驟:[0016](2.I.1)創(chuàng)建索引表:索引表表名為原數(shù)據(jù)表表名加上后綴"_scn",索引表僅包含一個列族"index",以不同的列表示不同的索引信息;索引數(shù)據(jù)具體的編排形式如下:[0017](TimeStamp,index:(ColunmnFamily_R,CoIumnFamiIy_C),(RowKey,Column))[0018]每行索引數(shù)據(jù)以數(shù)據(jù)變更發(fā)生的時間作為其行鍵值Timestamp;索引表中每條索引信息記錄兩列數(shù)據(jù)(ColunmnFamily_R,ColumnFamily_C),后綴為"_R"的列其值為該次變更事件所在數(shù)據(jù)單元的原數(shù)據(jù)表行鍵值RowKey;后綴為"_C"的列,保存該條數(shù)據(jù)在原數(shù)據(jù)表的列列名Column;原數(shù)據(jù)表中數(shù)據(jù)變更發(fā)生的列族名隱含地保存在索引表各行的列族名前綴ColunmnFamily之中;[0019](2.L2)利用Coprocessor運行框架在數(shù)據(jù)寫入HBase時同步地將相關(guān)索引數(shù)據(jù)記錄在索引表中;在為構(gòu)建索引數(shù)據(jù)構(gòu)建的jar包中,在Coprocessor.BaseRegionObserver基類的一個新的派生類中重載PostPut方法,具體包括以下子步驟:[0020](2.1.2.1)從寫入操作的Put實例中提取數(shù)據(jù)插入位置的行鍵值與原數(shù)據(jù)表表名,并以原數(shù)據(jù)表表名推斷其對應(yīng)的索引表表名;[0021](2.1.2.2)從Coprocessor框架提供的上下文中獲取輔助環(huán)境變量,可以利用該變量獲得對于任意數(shù)據(jù)表的連接;[0022](2.1.2.3)查看put實例中的所有的寫入數(shù)據(jù),遍歷由put.familyMap.keySetO方法返回的所有Key-Values鍵值對信息;[0023](2.I.2.4)提取遍歷到的每一個Key-Values鍵值對中的列族、列與時間戳信息,并將這些信息組織成一個以時間戳為行鍵值并以索引表格式組織的索引表put操作實例,將這些索引表put操作實例放入List列表PUtList待用;[0024](2.1.2.5)查看當(dāng)前緩存的索引表連接是否指向本次操作的索引表,若否利用輔助環(huán)境變量獲得該索引表的連接;[0025](2.L2.6)利用索引表連接,在索引表中通過scnTable.put(putList)寫入該次操作對應(yīng)的索引信息;[0026](2.1.3)捕獲器進程周期性地通過索引表中的數(shù)據(jù)捕獲原數(shù)據(jù)表中特定時間區(qū)間內(nèi)的數(shù)據(jù)變更事件,該時間區(qū)間由上一次捕獲完成時間與當(dāng)前捕獲時間共同決定,具體包括以下子步驟:[0027](2.1.3.1)依據(jù)數(shù)據(jù)變更捕獲配置,獲取本次數(shù)據(jù)抓取的原數(shù)據(jù)表表名,從其表名中推斷其對應(yīng)索引表表名;[0028](2.1.3.2)新建HBase數(shù)據(jù)表掃描實例Scan,設(shè)定該Scan的起始行鍵值為本次數(shù)據(jù)變更捕獲對應(yīng)的時間區(qū)間起點,終止行鍵值設(shè)置為0x7FFFFFFF或者當(dāng)前時間戳值;[0029](2.1.3.3)通過索引表表名獲取索引表連接,并應(yīng)用步驟2.1.3.2建立的Scan實例(htable.getScanner(Scan)),取得操作結(jié)果(由ResultScanner實例表不);[0030](2.1.3.4)迭代2.1.3.3操作結(jié)果中的每一行數(shù)據(jù),檢查其中所有列列名及其值,若其列列名后綴為R,記錄該列值為行鍵值RowKey,若該列列名后綴為C,記錄該列值為列名Column,最后從列族名中提取原表列族名ColumnFamily;[0031](2.1.3.5)利用步驟2.1.3.4中獲取的RowKey新建get實例,并加入列(ColumnFamiy,Column),并將該Get加入List列表getList待用;[0032](2.L3.6)利用原數(shù)據(jù)表表名獲取原數(shù)據(jù)表連接,并通過hTable.get(getList)取得索引記錄的數(shù)據(jù);[0033](2.1.3.7)迭代步驟2.1.3.6中返回的索引記錄數(shù)據(jù),將每一個數(shù)據(jù)單元的列族名、列、值、時間戳、類型數(shù)據(jù)組織成一個數(shù)據(jù)變更事件;[0034](2.2)創(chuàng)建第二類數(shù)據(jù)變更捕獲器,具體包括以下子步驟:[0035](2.2.1)獲得原數(shù)據(jù)表HBase集群使用的HDFS集群位置及其WAL文件所在路徑,并將所有的抓取任務(wù)按照HBase集群位置以及WAL文件所在HDFS文件路徑進行分類,所有由同一組(HBase集群位置,WAL文件路徑)標識的任務(wù)被組織成一個單一的任務(wù),屬于該組的所有變更捕獲任務(wù)均在一次WAL文件掃描中完成;[0036](當(dāng)前第1頁1 2 3