1.簡介
當HBase數據庫中存在非常重要的業務數據的時候為了保護數據的可以對數據進行備份處理。對於HBase來說從備份操作來看可分為離線備份和在線備份。
2. 前准備
在測試環境上准備有哦兩套HBase集群,資源有限原因他們共享一個hdfs集群和zookeeper,通過配置不同node路徑和數據路徑來區別開。
其中xufeng-1上的集群中沒有任何數據,xufeng-3集群上存在一些表和數據:
3.離線備份
離線備份顧名思義,在做備份的時候需要將集群停止,然后將集群在hdfs上的數據文件夾完整的拷貝到其他目錄或者其他hdfs上,之后可以使用讓其他集群或本集群重新加載這些數據從而達到備份的目的。之所以需要停止集群,因為如果集群處於服務狀態的話,如果拷貝過程中,有數據正在插入或者表正在被創建等就會造成備份的數據的內部沖突。
3.1需求
對於上述前准備的兩個集群,我們將xufeng-3這個集群上的數據備份出來,然后將這些數據直接拷貝到xufeng-1這個集群的對應的hdfs目中去。啟動集群xufeng-1檢查數據備份是否成功。
3.2 實現步驟:
步驟1:停止兩個集群
步驟2:刪除目標目錄文件夾
hadoop fs -rmr /hbase_backup
步驟3:由於在測試中實在同一個hdfs集群上拷貝數據的,所以這里簡單地使用了hadoop fs -cp 命令將xufeng-3集群對應的/hbase目錄下的所有內容拷貝到xufeng-1集群對應的/hbase_backup目錄中去。
hadoop fs -cp /hbase /hbase_backup
步驟4:啟動xufeng-1集群檢查結果:
hbase(main):001:0> list TABLE bulkload_test bulkload_text coprocessor_table mr_secondindex_resouce mr_secondindex_resource mr_secondindex_result mr_secondindex_test usertable 8 row(s) in 0.4480 seconds => ["bulkload_test", "bulkload_text", "coprocessor_table", "mr_secondindex_resouce", "mr_secondindex_resource", "mr_secondindex_result", "mr_secondindex_test", "usertable"] hbase(main):003:0> scan 'bulkload_test' ROW COLUMN+CELL rowKey10 column=f1:a, timestamp=1469912957257, value=a_10 rowKey10 column=f2:b, timestamp=1469912957257, value=b_10 rowKey6 column=f1:a, timestamp=1469912957257, value=a_6 rowKey6 column=f2:b, timestamp=1469912957257, value=b_6 rowKey7 column=f1:a, timestamp=1469912957257, value=a_7 rowKey7 column=f2:b, timestamp=1469912957257, value=b_7 rowKey8 column=f1:a, timestamp=1469912957257, value=a_8 rowKey8 column=f2:b, timestamp=1469912957257, value=b_8 rowKey9 column=f1:a, timestamp=1469912957257, value=a_9 rowKey9 column=f2:b, timestamp=1469912957257, value=b_9 5 row(s) in 0.3340 seconds
3.3 離線備份總結
通過上述方式讓一個新集群接收備份數據的前提是,這個集群必須是新建的純凈的,無論在zookeeper上都不能有垃圾數據。另外更加可靠的做法就是你可以先去備份數據,然后在建立hbase集群,在配置文件中將其目錄指定到備份文件的目錄即可。此種備份方法可以定時執行,因為並不是是實時備份,所以存在丟失數據的風險。
4. 在線備份
在線備份的意思是指不停止集群,將數據備份到同一個集群或者不同集群。好處顯而易見,業務不會停止。
在線備份的方法一般有三種:
- copyTable
- export and import
- replication
1.copyTable使用方法
這種方式通過MR計算框架將數據從源表中讀取出來,在將這些數據插入到目標集群的目標表中。讀取和插入都是走API 客戶端的。
1. 首先我們在兩個集群中建立兩張表,在xufeng-3的backup_test_copytable_source作為備份源表,在xufeng-1集群上的backup_test_copytable_dest表作為備份目標表。
需要注意的是: 兩個表的結構需要保持一致。
backup_test_copytable_source表結構:
hbase(main):003:0> describe 'backup_test_copytable_source' Table backup_test_copytable_source is ENABLED backup_test_copytable_source COLUMN FAMILIES DESCRIPTION {NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_ CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} {NAME => 'f2', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_ CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} 2 row(s) in 0.0450 seconds
backup_test_copytable_dest表結構:
hbase(main):019:0> describe 'backup_test_copytable_dest' Table backup_test_copytable_dest is ENABLED backup_test_copytable_dest COLUMN FAMILIES DESCRIPTION {NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEE P_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 't rue'} {NAME => 'f2', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEE P_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 't rue'} {NAME => 'f3', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEE P_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 't rue'}
2.保持backup_test_copytable_dest表為空。我們在backup_test_copytable_source中插入測試數據,其中在f1列族和f2列族上都插入數據:
hbase(main):002:0> scan 'backup_test_copytable_source' ROW COLUMN+CELL row1 column=f1:a, timestamp=1469925544667, value=f1aValue row1 column=f1:b, timestamp=1469925535422, value=f1bValue row1 column=f2:a, timestamp=1469925564187, value=f2aValue row1 column=f2:b, timestamp=1469925573770, value=f2bValue row2 column=f1:a, timestamp=1469925646986, value=f1aValue row2 column=f1:b, timestamp=1469925653872, value=f1bValue row2 column=f2:a, timestamp=1469925662058, value=f2aValue row2 column=f2:b, timestamp=1469925667362, value=f2bValue
3.需求:我們需要將backup_test_copytable_source的f1列族下的數據備份到backup_test_copytable_dest的f1列族中:
在xufeng-3備份源集群上執行:
HADOOP_CLASSPATH=`/opt/hadoop/hbase/bin/hbase classpath` hadoop jar hbase-server-1.0.0-cdh5.4.2.jar copytable --families=f1 --peer.adr=xufeng-1:2181:/hbase_backup --new.name=backup_test_copytable_dest backup_test_copytable_source
其中:
--families:需要備份的列族信息
--peer.adr:目標集群在zookeeper的根節點信息,也就指明了目標集群的訪問地址
--new.name:備份目標表名
最后執行備份源表名要將backup_test_copytable_source的f1列族
4.上述命令會執行MR任務,最后會將數據拷貝的目標表中:
hbase(main):021:0> scan 'backup_test_copytable_dest' ROW COLUMN+CELL row1 column=f1:a, timestamp=1469925544667, value=f1aValue row1 column=f1:b, timestamp=1469925535422, value=f1bValue row2 column=f1:a, timestamp=1469925646986, value=f1aValue row2 column=f1:b, timestamp=1469925653872, value=f1bValue 2 row(s) in 0.1820 seconds
5. 除了上述參數外,也可以通過starttime和endtime參數來指定備份的時間段,這樣我們可以進行增量備份。但是由於數據的timestamp用戶插入數據的時候可以指定的,所以根據starttime/endtime來進行增量備份的時候需要業務配合,插入數據的時候不要指定timestamp值,或者插入的timestamp值有增量的特點。
具體的copytable使用方法可以參考:
[hadoop@xufeng-3 lib]$ HADOOP_CLASSPATH=`/opt/hadoop/hbase/bin/hbase classpath` hadoop jar hbase-server-1.0.0-cdh5.4.2.jar copytable Usage: CopyTable [general options] [--starttime=X] [--endtime=Y] [--new.name=NEW] [--peer.adr=ADR] <tablename> Options: rs.class hbase.regionserver.class of the peer cluster specify if different from current cluster rs.impl hbase.regionserver.impl of the peer cluster startrow the start row stoprow the stop row starttime beginning of the time range (unixtime in millis) without endtime means from starttime to forever endtime end of the time range. Ignored if no starttime specified. versions number of cell versions to copy new.name new table's name peer.adr Address of the peer cluster given in the format hbase.zookeeer.quorum:hbase.zookeeper.client.port:zookeeper.znode.parent families comma-separated list of families to copy To copy from cf1 to cf2, give sourceCfName:destCfName. To keep the same name, just give "cfName" all.cells also copy delete markers and deleted cells bulkload Write input into HFiles and bulk load to the destination table Args: tablename Name of the table to copy Examples: To copy 'TestTable' to a cluster that uses replication for a 1 hour window: $ bin/hbase org.apache.hadoop.hbase.mapreduce.CopyTable --starttime=1265875194289 --endtime=1265878794289 --peer.adr=server1,server2,server3:2181:/hbase --families=myOldCf:myNewCf,cf2,cf3 TestTable For performance consider the following general option: It is recommended that you set the following to >=100. A higher value uses more memory but decreases the round trip time to the server and may increase performance. -Dhbase.client.scanner.caching=100 The following should always be set to false, to prevent writing data twice, which may produce inaccurate results. -Dmapreduce.map.speculative=false
6.copyTable備份總結:
此方法使得在兩個集群同時online的時候進行備份,與離線備份一樣,由於需要周期性的執行,也會存在數據丟失的風險。
通過copytable方法是針對單個表的備份操作,如果需要進行多個表的備份需要分別處理。
另外由於是通過api的方式讀取備份源表的數據,所以勢必會造成備份源數據的性能下降。
2.export and import
這種方法通過export工具執行MR任務讀取HBase表數據(通過HBase 客戶端)dump到相同集群的hdfs上,文件的格式是sequence格式的,在dump的時候可以指定MR的參數來進行壓縮。
后續如果需要restore數據的時候通過import將dump下來的文件通過MR任務進行數據插入(通過HBase客戶端)。
1. 在xufeng-3備份源集群上創建如下表並插入數據:
hbase(main):002:0> create 'backup_test_exporttable_source','f1','f2' 0 row(s) in 1.4780 seconds hbase(main):012:0> scan'backup_test_exporttable_source' ROW COLUMN+CELL row1 column=f1:a, timestamp=1469931540396, value=f1-a row1 column=f1:b, timestamp=1469931546015, value=f1-b row1 column=f2:a, timestamp=1469931556171, value=f2-a row1 column=f2:b, timestamp=1469931551950, value=f2-b row2 column=f1:a-2, timestamp=1469931578074, value=f1-a-2 row2 column=f1:b-2, timestamp=1469931585208, value=f1-b-2 row2 column=f2:a-2, timestamp=1469931595183, value=f2-a-2 row2 column=f2:b-2, timestamp=1469931641553, value=f2-b-2
2.xufeng-3集群上通過如下命令出發dump文件MR任務:
HADOOP_CLASSPATH=`/opt/hadoop/hbase/bin/hbase classpath` hadoop jar hbase-server-1.0.0-cdh5.4.2.jar export -D mapreduce.output.fileoutputformat.compress=true -D mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec -D mapreduce.output.fileoutputformat.compress.type=BLOCK backup_test_exporttable_source /backuptestdata/backup_test_exporttable_source_dumpfiles
其中通過-D指令來想MR任務配置參數,這里我們設置其在block上進行gzip的壓縮算法。最后兩個參數是表名和dump到的目標文件夾目錄。
上述任務會通過HBase的API進行表的scan然后將結果存儲到文件中去。
3.查看hdfs文件系統確認dump的文件結果:
[hadoop@xufeng-1 ~]$ hadoop fs -ls /backuptestdata/backup_test_exporttable_source_dumpfiles 16/07/30 22:36:02 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Found 2 items -rw-r--r-- 1 hadoop supergroup 0 2016-07-30 22:32 /backuptestdata/backup_test_exporttable_source_dumpfiles/_SUCCESS -rw-r--r-- 1 hadoop supergroup 409 2016-07-30 22:32 /backuptestdata/backup_test_exporttable_source_dumpfiles/part-m-00000
4。除了上述名另外我們還可以指定數據的版本號和開始timestamp和結束timestamp來進行增量的dump備份,當然如copytable一樣,對於timestamp的增量備份需要業務配合,最好是插入數據的時候不要認為指定。
具體其還有那些參數可以參看export的具體使用方法:
[hadoop@xufeng-3 lib]$ HADOOP_CLASSPATH=`/opt/hadoop/hbase/bin/hbase classpath` hadoop jar hbase-server-1.0.0-cdh5.4.2.jar export ERROR: Wrong number of arguments: 0 Usage: Export [-D <property=value>]* <tablename> <outputdir> [<versions> [<starttime> [<endtime>]] [^[regex pattern] or [Prefix] to filter]] Note: -D properties will be applied to the conf used. For example: -D mapreduce.output.fileoutputformat.compress=true -D mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec -D mapreduce.output.fileoutputformat.compress.type=BLOCK Additionally, the following SCAN properties can be specified to control/limit what is exported.. -D hbase.mapreduce.scan.column.family=<familyName> -D hbase.mapreduce.include.deleted.rows=true -D hbase.mapreduce.scan.row.start=<ROWSTART> -D hbase.mapreduce.scan.row.stop=<ROWSTOP> For performance consider the following properties: -Dhbase.client.scanner.caching=100 -Dmapreduce.map.speculative=false -Dmapreduce.reduce.speculative=false For tables with very wide rows consider setting the batch size as below: -Dhbase.export.scanner.batch=10
5.對於上述dump出的文件會放在與HBase集群同樣資源的hdfs上,所以建議可以拷貝的外部hdfs集群或者通過外部介質存儲。
6.現在表已經dump出來了,如何restore呢?我們在另外一個HBase集群xufeng-3上建立表,這個表的結構需要和備份源表列族等信息結構一致:
hbase(main):005:0> create 'backup_test_exporttable_dest','f1','f2'
0 row(s) in 6.8200 seconds
hbase(main):010:0> scan 'backup_test_exporttable_dest'
ROW COLUMN+CELL
0 row(s) in 0.0200 seconds
7.通過如下命令將數據restore到目標表中去。
HADOOP_CLASSPATH=`/opt/hadoop/hbase/bin/hbase classpath` hadoop jar hbase-server-1.0.0-cdh5.4.2.jar import backup_test_exporttable_dest /backuptestdata/backup_test_exporttable_source_dumpfiles
這個命令比較簡單,只要指定目標表和dump文件父路徑即可。
上述命令會讀取dump命令中的內容然后組裝成put將數據插入的目標表中去。
8.檢查目標表數據
=> ["backup_test_copytable_dest", "backup_test_exporttable_dest"] hbase(main):002:0> scan 'backup_test_exporttable_dest' ROW COLUMN+CELL row1 column=f1:a, timestamp=1469931540396, value=f1-a row1 column=f1:b, timestamp=1469931546015, value=f1-b row1 column=f2:a, timestamp=1469931556171, value=f2-a row1 column=f2:b, timestamp=1469931551950, value=f2-b row2 column=f1:a-2, timestamp=1469931578074, value=f1-a-2 row2 column=f1:b-2, timestamp=1469931585208, value=f1-b-2 row2 column=f2:a-2, timestamp=1469931595183, value=f2-a-2 row2 column=f2:b-2, timestamp=1469931641553, value=f2-b-2 2 row(s) in 0.3430 seconds
9.總結
export和import的組合使用可以進行數據的文件落地然后在restore,他們都是MR任務通過HBase API進行數據的讀取和插入。對於dump出來的文件建議放在不同的hdfs集群上避免丟失。
3. replication
此種機制相對來說比較復雜,其實HBase本省的備份機制。前述的幾種方法都是借用MR和HBAse客戶端進行數據的轉移。
對於replication的用戶會在另外的博文中演示說明HBase集群備份方法--Replication機制
5.總計
對於生產版本的數據的維護都是如履薄冰,備份機制可以讓我們在現有集群宕機或者損毀的情況下繼續有備份集群進行快速的數據恢復和提供服務。