常見的HBase數(shù)據(jù)遷移和備份的方式
我們知道目前HBase可以通過如下幾種方式對數(shù)據(jù)進行數(shù)據(jù)的遷移和備份:
1富拗、通過distcp命令拷貝hdfs文件的方式實現(xiàn)數(shù)據(jù)的遷移和備份
? ? 這種方式使用MapReduce實現(xiàn)文件分發(fā)搪桂,把文件和目錄的列表當做map任務(wù)的輸入涨颜,每個任務(wù)完成部分文件的拷貝和傳輸工作。在目標集群再使用bulkload的方式導(dǎo)入就實現(xiàn)了數(shù)據(jù)的遷移。
? ? 這種方式不好的地方在于需要停寫则剃,不然會導(dǎo)致數(shù)據(jù)不一致拢切,比較適合遷移歷史表(數(shù)據(jù)不會被修改的情況)
2、通過copytable的方式實現(xiàn)表的遷移和備份
這種方式是以表級別進行遷移的猎物,其本質(zhì)也是使用MapReduce的方式進行數(shù)據(jù)的同步虎囚,和上面distcp不一樣的是嗎,copytable的方式是利用MapReduce去scan源表的數(shù)據(jù)蔫磨,然后把scan出來的數(shù)據(jù)寫到目標集群淘讥,從而實現(xiàn)數(shù)據(jù)的遷移和備份。
? ? 這種方式相當于邏輯備份堤如,需要通過大量的scan數(shù)據(jù)蒲列,對于很大的表,如果這個表本身又讀寫比較頻繁的情況下搀罢,會對性能造成比較大的影響蝗岖,并且效率比較低。
3榔至、通過replication的方式實現(xiàn)表的復(fù)制
? ? 這種方式類似mysql的同步方式抵赢,HBase通過同步WAL日志中所有變更來實現(xiàn)表的同步,異步同步唧取。
?? ?這種方式需要在兩個集群數(shù)據(jù)一樣的情況下開啟復(fù)制铅鲤,默認復(fù)制功能是關(guān)閉的,配置后需要重啟集群枫弟,并且如果主集群數(shù)據(jù)有出現(xiàn)誤修改邢享,備集群的數(shù)據(jù)也會有問題。
4淡诗、通過Export/Import的方式實現(xiàn)表的遷移和備份
這種方式和copytable的方式類似骇塘,將HBase表的數(shù)據(jù)轉(zhuǎn)換成Sequence File并dump到HDFS,也涉及Scan表數(shù)據(jù)韩容。和copytable不同的是款违,Export不是將HBase的數(shù)據(jù)scan出來直接Put到目標集群,而是先轉(zhuǎn)換成文件并同步到目標集群宙攻,再通過Import的方式導(dǎo)到對應(yīng)的表中奠货。
? ? 這種方式需要scan數(shù)據(jù),也會對HBase造成負載的影響座掘,效率不高递惋。
5柔滔、通過snapshot的方式實現(xiàn)表的遷移和備份
? ? 這種方式就是我們今天要重點介紹的HBase快照,通過快照的方式實現(xiàn)HBase數(shù)據(jù)的遷移和拷貝萍虽。這種方式比較常用睛廊,效率高,也是最為推薦的數(shù)據(jù)遷移方式杉编。
綜上超全,我們可以分析了各種HBase數(shù)據(jù)的遷移和備份的方式的優(yōu)劣,強烈推薦使用snapshot的方式來進行數(shù)據(jù)的遷移和備份邓馒,那么什么是snapshot嘶朱?原理是什么?以及如何使用snap光酣?在下面的篇幅中就來詳細介紹一下HBase的快照功能疏遏。
一、HBase快照簡介
? ?HBase快照(snapshot)顧名思義就是在某個時刻對某個HBase表的數(shù)據(jù)做了快速備份救军,就像拍照一下财异,讓數(shù)據(jù)停留在那個時刻不再變動,后面用來做數(shù)據(jù)的恢復(fù)或者遷移唱遭。HBase在0.94版本開始提供了快照功能戳寸,0.95版本以后默認開啟快照功能。
? ? HBase的snapshot其實就是一組metadata信息的集合(文件列表)拷泽,通過這些metadata信息的集合疫鹊,就能將表的數(shù)據(jù)回滾到snapshot那個時刻的數(shù)據(jù)。
二跌穗、HBase快照使用場景
? ? 簡單概括HBase快照的使用場景如下:
? ? 1订晌、HBase表的定期快速備份
? ? 2虏辫、升級前的HBase數(shù)據(jù)備份
? ? 3蚌吸、集群間的數(shù)據(jù)遷移
? ? 4、構(gòu)建測試環(huán)境數(shù)據(jù)
? ? 5砌庄、做數(shù)據(jù)恢復(fù)
三羹唠、HBase快照的詳細原理
? ? 既然HBase的snapshot能快速實現(xiàn)HBase的數(shù)據(jù)備份,那么具體是怎么做到的呢娄昆? 如何保證快照完后數(shù)據(jù)的完整性佩微、一致性問題?下面就來詳細介紹一下HBase快照的原理萌焰。
在介紹HBase的snapshot之前哺眯,首先我們要了解一下所謂的HBase的LSM類型的系統(tǒng)結(jié)構(gòu),我們知道在HBase中扒俯,數(shù)據(jù)是先寫入到Memstore中奶卓,當Memstore中的數(shù)據(jù)達到一定條件一疯,就會flush到HDFS中,形成HFile夺姑,后面就不允許原地修改或者刪除了墩邀。如果要更新或者刪除的話,只能追加寫入新文件盏浙。
? ? 既然數(shù)據(jù)寫入以后就不會在發(fā)生原地修改或者刪除眉睹,這就是snapshot做文章的地方。做snapshot的時候废膘,只需要給快照表對應(yīng)的所有文件創(chuàng)建好指針(元數(shù)據(jù)集合)竹海,恢復(fù)的時候只需要根據(jù)這些指針找到對應(yīng)的文件進行恢復(fù)就Ok。這是原理的最簡單的描述丐黄,下圖是描述快照時候的簡單流程:
由上圖可以看出創(chuàng)建snapshot的流程主要分為4個步驟站削,分別是:
1、對該表添加全局鎖孵稽,不允許任何數(shù)據(jù)的寫入许起、更新和刪除
2、將該表內(nèi)存中的數(shù)據(jù)(memstore)flush到HFile文件中
3菩鲜、為該表涉及的各個region中所有HFile文件創(chuàng)建引用指針园细,并記錄到snapshot文件中
4、Hmaster將所有的region的snapshot文件進行匯總形成總體的snapshot文件
四接校、HBase相關(guān)問題解析
? ? 了解了HBase快照的原理猛频,這里自然就會有一些疑惑,下面是我再學(xué)習(xí)HBase快照的疑惑蛛勉。
問題1:HBase的HFile會存在合并的機制鹿寻,當HFile合并了以后,就不再是原來的HFile了诽凌,那么快照是如何保證在HFile合并后防止snapshot失效的問題毡熏?
解答:HBase的實現(xiàn)是將原始表的數(shù)據(jù)復(fù)制到archive目錄下,再進行compact侣诵,這樣spapshot就不會因為HBase的合并而失效了痢法。在做完快照以后,你可以嘗試對該表做major_compact操作杜顺,執(zhí)行major_compact后财搁,就能在archive目錄下看到對應(yīng)表的相關(guān)備份文件了。
問題2:如果一個表存在大量的region躬络,在做快照的時候尖奔,那么多的region都需要做快照,那些region又分布在不同的regionserver上,怎么保證全部都能成功或者失斕嶙隆仗嗦?
解答:HBase采用兩階段提交的方式來保證snapshot的原子性,要么成功甘凭,要么失敗稀拐。兩階段提交分為prepare階段和commit階段,具體步驟如下:
1丹弱、prepare階段:在prepare階段HMaster在zookeeper上創(chuàng)建一個’/acquired-snapshot’節(jié)點德撬,并記錄snapshot表的相關(guān)信息。所有regionserver監(jiān)測到這個節(jié)點后躲胳,會獲取/acquired-snapshot節(jié)點中snapshot表的相關(guān)信息蜓洪,并查看自身服務(wù)器上是否存在snapshot表的相關(guān)region,如果不存在坯苹,就忽略隆檀。如果存在就那些region做snapshot,并將snapshot的結(jié)果寫入到臨時文件夾【備注:之所以寫入臨時文件夾粹湃,是為了再失敗的時候回滾方便】恐仑。regionserver再執(zhí)行完后會在/acquired-snapshot下新建一個子節(jié)點/acquired-snapshot/nodex,表示nodex完成了該regionserver上所有相關(guān)region的snapshot的準備工作为鳄。
2裳仆、commit階段:一旦Hmaster檢查到/acquired-snapshot目錄下的子節(jié)點全部都已經(jīng)創(chuàng)建,則認為snapshot的prepare的階段已經(jīng)完成孤钦,這個時候歧斟,Hmaster會在ZK上創(chuàng)建一個新的節(jié)點/reached-snapshotname,表示發(fā)一個commit命令給參與的regionserver偏形,regionserver監(jiān)測到/reached-snapshotname節(jié)點后静袖,就執(zhí)行snapshot的commit操作。commit的操作只是將prepare階段寫到臨時目錄的snapshot結(jié)果移動到最終的文件夾中俊扭。執(zhí)行成功后队橙,regionserver會在/reached-snapshotname下創(chuàng)建/reached-snapshotname/nodex節(jié)點,表示nodex完成了snapshot工作统扳。
如果所有參與的regionserver都在/reached-snapshotname下創(chuàng)建的子節(jié)點喘帚,則Hmaster確認快照創(chuàng)建已經(jīng)成功畅姊。如果一定時間內(nèi)咒钟,/reached-snapshotname下的子節(jié)點沒有滿足條件或者prepare階段中/acquired-snapshot下的子節(jié)點不滿足條件,則會進入第3個節(jié)點若未,abort階段
3朱嘴、abort階段:HMaster會認為快照創(chuàng)建超時,進行回滾操作。此時Hmaster會在ZK上創(chuàng)建/abort-snapshotname節(jié)點萍嬉,所有regionserver監(jiān)聽到會清理臨時snapshot在臨時文件夾中的生成結(jié)果乌昔。
五、HBase快照實戰(zhàn)
1壤追、創(chuàng)建snapshot
?? ?snapshot 'tableName',?‘snapshotName'
2磕道、查看snapshot
list_snapshots
? ? 查找以map開頭的snapshot
list_snapshots 'map.*'
3、刪除snapshot
delete_snapshot 'snapshotName'
4行冰、遷移snapshot
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \
?? ?-snapshot snapshot_src_table \
?? ?-copy-fromhdfs://src-hbase-root-dir/hbase\
?? ?-copy-tohdfs://dst-hbase-root-dir/hbase\
?? ?-mappers 20 \
?? ?-bandwidth 1024
? ? 這種方式用于將快照表遷移到另外一個集群的時候使用溺蕉,使用MR進行數(shù)據(jù)的拷貝,速度很快悼做,使用的時候記得設(shè)置好bandwidth參數(shù)疯特,以免由于網(wǎng)絡(luò)打滿導(dǎo)致的線上業(yè)務(wù)故障。
5肛走、恢復(fù)snapshot
restore_snapshot ‘snapshotName’
? ? 備注:這種方式需要對表進行過disable才能進行restore_snapshot的操作漓雅,如果這個還在寫入數(shù)據(jù),則需要采用bulkload的方式導(dǎo)入朽色。
6邻吞、將snapshot使用bulkload的方式導(dǎo)入
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles \
?? ?-Dhbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily=1024 \
?? ?hdfs://dst-hbase-root-dir/hbase/archive/datapath/tablename/filenametablename
? ? 備注1:這種方式需要將所有的文件進行遍歷并全部通過bulkload導(dǎo)入,上面的只是一個文件的導(dǎo)入葫男,這種方式不需要disable表吃衅。
備注2:? 上面的操作1、2腾誉、3徘层、5都是在hbase shell中執(zhí)行。
參考資料
Introduction to Apache HBase Snapshots:http://blog.cloudera.com/blog/2013/03/introduction-to-apache-hbase-snapshots/
Introduction to Apache HBase Snapshots, Part 2: Deeper Dive:http://blog.cloudera.com/blog/2013/06/introduction-to-apache-hbase-snapshots-part-2-deeper-dive/
http://hbasefly.com/2017/09/17/hbase-snapshot/
http://km.oa.com/group/26245/articles/show/325482