HBase集群备份方法

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. 在线备份

  在线备份的意思是指不停止集群,将数据备份到同一个集群或者不同集群。好处显而易见,业务不会停止。

在线备份的方法一般有三种:

  1. copyTable
  2. export and import
  3. 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.总计

  对于生产版本的数据的维护都是如履薄冰,备份机制可以让我们在现有集群宕机或者损毁的情况下继续有备份集群进行快速的数据恢复和提供服务。 

posted on 2019-08-06 09:48  大数据运维  阅读(1500)  评论(0编辑  收藏  举报

导航