HBase不同版本集群之间数据迁移

由于HBase CDH4和CDH5数据格式不兼容,所以不能用“CopyTable”之类的方法来进行数据迁移。取而代之的方法有两个:

export + distcp + import

  • export

在CDH4集群上,将制定表的数据导出为sequence file到指定目录,基本命令如下

1
hbase org.apache.hadoop.hbase.mapreduce.Export [options] <tablename> <export_directory>

tablename: 需要导出的表名

export_directory: 数据导出到的hdfs目录

options:可以指定参数用于精细化的控制,格式为[-D <property=value>]*,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
指定导出的sequence file压缩格式:
-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

控制导出的内容:
-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>

控制导出性能:
-D hbase.client.scanner.caching=100
-D mapreduce.map.speculative=false
-D mapreduce.reduce.speculative=false

对于大宽表,建议设置batch size:
-D hbase.export.scanner.batch=10

  • distcp

将CDH4集群导出到export_directory目录中的sequence file拷贝到CDH5集群,这里用到hadoop的distcp命令,用于在不同hadoop集群间拷贝文件

1
hadoop distcp -p -update -skipcrccheck hftp://cdh4-namenode:port/export_directory hdfs://cdh5-namenode/import_directory

注意distcp命令一定要在目标集群(CDH5)上执行

distcp会在文件拷贝完成后比较源文件和目标文件的checksum,由于CDH4和CDH5的默认checksum算法不一致,CDH4使用CRC32,CDH5使用CRC,因此任务有可能会失败,这里指定-skipcrccheck可以忽略这一步骤,或者通过-Ddfs.checksum.type=CRC32来指定checksum算法

  • import

在import之前,需要先在CDH5集群建表,column family必须和CDH4的表保持一致

然后将distcp过来的sequence file导入HBase表中,命令如下

1
hbase -Dhbase.import.version=0.94 org.apache.hadoop.hbase.mapreduce.Import <tablename> <import_directory>

hbase.import.version指定源集群(CDH4)的HBase版本

拷贝HFile

另一种方案是直接将HFile从CDH4拷贝到CDH5的hdfs文件系统里,然后升级HFile

  • distcp
1
hadoop distcp -p -update -skipcrccheck webhdfs://cdh4-namenode:http-port/hbase hdfs://cdh5-namenode:rpc-port/hbase
  • upgrade

启动CDH5集群,HBase会自动检测并升级HFile

总结


总体来讲第一种方案耗时更长,因为需要进行三次mapreduce,但更建议用第一种方案,import/export的机制拥有更高的灵活性,你可以定时增量的迁移数据。除非数据量太大导致export和import耗费太长时间才考虑第二种方案。

———————————- 我是分割线 ——————————————–

之前说到第二种方案做upgrade时需要重启集群,实际上有办法避免,方法如下

  • 拷贝.tableinfo.0000000001文件
1
2
hadoop fs -mkdir -p /hbase/data/default/<tablename>/.tabledesc
hadoop fs -mv /hbase/data/default/<tablename>/.tableinfo.0000000001 /hbase/data/default/<tablename>/.tabledesc

注:这一步是因为CDH4的.tableinfo.0000000001文件在根目录下,CDH5的在.tabledesc下

  • 修复meta
1
hbase hbck -fixMeta
  • 重新分配rs
1
hbase hbck -fixAssignments
  • 完工