摘要:掌握Snapshot能夠幫助咱們很好的完成HBase數據備份和數據遷移的工做。
本文分享自華爲雲社區《看看HBase Snapshot中表的文件是怎樣變化的》,原文做者:Lettle whale 。java
HBase的Snapshot功能能夠在不復制數據的狀況下,快速克隆一張表,完成一次數據備份。經過Snapshot,咱們在作應用升級以前生成一個快照,後續若是遇到問題能夠快速回滾到快照點。Snapshot過程不涉及底層數據文件的拷貝和移動,只是對文件作了記錄,保存了一份原始文件的指針記錄,因此很是迅速,掌握Snapshot能夠幫助咱們很好的完成HBase數據備份和數據遷移的工做。segmentfault
● 對一個表「mytable「,執行快照命令工具
hbase(main):078:0> snapshot 'mytable','snapshot-test' 0 row(s) in 1.1110 seconds
● 在HDFS目錄下.hbase-snapshot中會生成一個生成一個以快照名字「snapshot-test」命名的snapshot文件夾ui
(本文HDFS中hbase的根目錄爲/d-hbase)spa
./hdfs dfs -ls /d-hbase/.hbase-snapshot Found 2 items drwxr-xr-x - root supergroup /d-hbase/.hbase-snapshot/.tmp drwxr-xr-x - root supergroup /d-hbase/.hbase-snapshot/snapshot-test
● Region的全部元數據及HFile信息會記錄到snapshot文件夾中,文件夾中有2個文件,其中.snapshotinfo爲snapshot基本信息,包含表名稱和snapshot名,data.manifest爲snapshot執行後生成的元數據信息,裏面包含了表的schema信息,region信息,以及HFile指針指針
./hdfs dfs -ls /d-hbase/.hbase-snapshot/snapshot-test Found 2 items -rw-r--r-- 1 root supergroup /d-hbase/.hbase-snapshot/snapshot-test/.snapshotinfo -rw-r--r-- 1 root supergroup /d-hbase/.hbase-snapshot/snapshot-test/data.manifest
這裏咱們經過Java代碼去解讀這兩個文件,參考HBase的工具類ExportSnapshot.java中對快照文件的解析代碼code
final List<Pair<SnapshotProtos.SnapshotFileInfo, Long>> files = new ArrayList<>(); HBaseProtos.SnapshotDescription snapshotDesc = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir); final TableName table = TableName.valueOf(snapshotDesc.getTable()); SnapshotReferenceUtil.visitReferencedFiles(conf, fs, snapshotDir, snapshotDesc, (regionInfo, family, storeFile) -> { if (!storeFile.hasReference()) { String region = regionInfo.getEncodedName(); String hfile = storeFile.getName(); Path path = HFileLink.createPath(table, region, family, hfile); SnapshotProtos.SnapshotFileInfo fileInfo = SnapshotProtos.SnapshotFileInfo.newBuilder().setType(SnapshotProtos.SnapshotFileInfo.Type.HFILE).setHfile(path.toString()).build(); long size; if (storeFile.hasFileSize()) { size = storeFile.getFileSize(); } else { size = HFileLink.buildFromHFileLinkPattern(conf, path).getFileStatus(fs).getLen(); } files.add(new Pair<>(fileInfo, size)); } });
經過讀取.snapshotinfo獲得了snapshotDesc,這個對象中,主要包含了本次snapshot的name和table對象
經過讀取data.manifest獲得了本次Snapshots涉及到哪些region以及關聯的HFileblog
這裏解析出來的路徑格式爲 <列族>/<表名>=<reigon名>-<HFile>ip
解析這個格式,就能獲得 「表名」,「列族」,「region」,「HFile」,有了上述信息,就基本可以找到原始的HFile路徑。這個HFile的位置可能在data目錄下面,也可能在archive目錄中,由於表進行過major_compact,HFile會進入archive目錄下。因此ExportSnapshot工具在查找snapshot對應的HFile文件時,也是找的data目錄或者archive目錄。
接下來看一下,對clone_snapshot複製出來的表再進行snapshot快照,表中的文件變化是怎樣的
執行命令,使用snapshot複製出一張表「clone_table」
clone_snapshot 'snapshot-test', 'clone_table'
查看clone出來的表的文件路徑,能夠看到這裏的HFile實際上是個連接文件,連接的是"mytable"表下的eddf78bf298819342f48b8199b3e5269這個Region的5b089dc6f7ca4fb8932aa2899a85f9b2文件
./hdfs dfs -ls /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam Found 1 items -rw-r--r-- 1 root supergroup /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam/mytable=eddf78bf298819342f48b8199b3e5269-5b089dc6f7ca4fb8932aa2899a85f9b2
此時觀察原始表"mytable"的archive下,已經有一個back-reference文件,以.links-開頭的
./hdfs dfs -ls /d-hbase/archive/data/default/mytable/eddf78bf298819342f48b8199b3e5269/fam Found 1 items drwxr-xr-x - root supergroup /d-hbase/archive/data/default/mytable/eddf78bf298819342f48b8199b3e5269/fam/.links-5b089dc6f7ca4fb8932aa2899a85f9b2
若是此時對clone表,作major_compact
major_compact 'clone_table'
此時會生成一個新的region文件,這是一個真實的數據文件
./hdfs dfs -ls /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam Found 2 items -rw-r--r-- 1 root supergroup 5084 /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam/50a43588d8b145f89a46649d34ecea42 -rw-r--r-- 1 root supergroup 0 /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam/mytable=eddf78bf298819342f48b8199b3e5269-5b089dc6f7ca4fb8932aa2899a85f9b2
那個連接文件「mytable=eddf78bf298819342f48b8199b3e5269-5b089dc6f7ca4fb8932aa2899a85f9b2」,被移除
./hdfs dfs -ls /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam Found 1 items -rw-r--r-- 1 root supergroup 5084 /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam/50a43588d8b145f89a46649d34ecea42
接着對上面那個」clone_table「表進行split,並在split過程當中的同時執行snapshot
split 'clone_table','3' snapshot 'clone_table','clone_table_snapshot'
初始時,在data目錄下,父reigon的目錄9fe93242bd8a96c80f350f829504cba2目錄仍然在,
./hdfs dfs -ls /d-hbase/data/default/clone_table/ Found 5 items drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/.tabledesc drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/.tmp drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/4169b0c3083febcc11ed6e8e716d6f93 drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/611efc98e1c72502a0c31536866c4cce drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2
分裂完成後,data目錄下的父region目錄9fe93242bd8a96c80f350f829504cba2被移除
./hdfs dfs -ls /d-hbase/data/default/clone_table/ Found 4 items drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/.tabledesc drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/.tmp drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/4169b0c3083febcc11ed6e8e716d6f93 drwxr-xr-x - root supergroup 0 /d-hbase/data/default/clone_table/611efc98e1c72502a0c31536866c4cce
同時觀察archive目錄,一開始也是有父reigon和子region的目錄,子reigon裏面的文件是split產生的reference文件,連接的是父reigon的HFile,都是「50a43588d8b145f89a46649d34ecea42-9fe93242bd8a96c80f350f829504cba2」
過了幾分鐘後,只剩下了父reigon的目錄
./hdfs dfs -ls /d-hbase/archive/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam Found 1 items -rw-r--r-- 1 root supergroup 5084 /d-hbase/archive/data/default/clone_table/9fe93242bd8a96c80f350f829504cba2/fam/50a43588d8b145f89a46649d34ecea42
此時,再經過以前的java代碼分析data.manifest中的信息,
發現這裏是包含父Region以及分裂後的2個子Region的HFile信息,且關聯的子Region裏的HFile也是分裂後真實存在的。
這裏忽然有個疑問,假如後面根據這個文件信息去恢復數據時,會不會重複去把父Region和子Region都去恢復,因而執行了ExportSnapshot命令,將snapshot對應的文件到導出來,導出來的也是包含這3個Region的真實數據文件,這代表此過程當中的確會出現有重複數據文件的問題,雖然多個文件會包含同一份數據,不過對業務不會有影響,會隨着後續Compact消除掉。
後續繼續作了幾回相同的試驗,在split過程當中執行snapshot,data.manifest中有時候出現1個父Region和2個子Region的信息,有時候出現1個父Region和1個子Region的信息,說明打快照是對錶的HFile瞬時的記錄,並不會特地去等待分裂完成。
能夠基於快照的原理去開發HBase全量數據遷移工具,解析快照元數據,得到表的全部文件路徑列表,從而不依賴ExportSnapshot工具,進行更靈活的文件遷移,將表的全部文件經過流的方式拷貝到目的集羣HDFS中,進而可使用LoadIncrementalHFiles這樣的工具,將HFile裝載到新的表中。