最近有个工作是把数据从CDH5.8迁移到新集群CDH6.1,数据迁移首先想到的就是hadoop distcp命令,distcp(distributed copy)是用于大型集群间/集群内复制的工具。它使用MapReduce来实现其分发,错误处理和恢复以及报告。它将文件和目录的列表扩展为映射任务的输入,每个任务都会复制源列表中指定的文件分区。

同版本集群间数据迁移

对于Hadoop版本一致或差一两个小版本,可以使用HDFS协议即可,在target集群运行如下命令

1
hadoop distcp hdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo

其中hdfs://nn1:8020/foo/barsource集群,hdfs://nn2:8020/bar/foo为目标集群。

不同版本集群减数据迁移

对于版本差距较大,互相不兼容的集群,可以使用hftp协议webhdfs来实现数据迁移。

hftp协议

target集群运行如下命令:

1
hadoop distcp hftp://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo

webhdfs(推荐)

确保source集群开启了webhdfs,在target集群运行如下命令:

1
hadoop distcp  webhdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo

hadoop distcp参数

对于distcp命令来说,还可以使用如下常用的参数来调整其运行配置:

  • -p [rbugpcaxt] : 禁止
    • r (副本数量)
    • b (块大小)
    • u (用户)
    • g (组)
    • p (权限)
    • c (Checksum 类型)
    • a (ACL)
    • x (xAttr)
    • t (时间戳)
  • -m : 同时拷贝的最大map数量
  • -overwrite : 覆盖target集群已存在的数据
  • -i 忽略失败
  • -bandwidth 指定每个map的带宽,单位MB/s
  • -update 如果sourcetarget的数据块大小、checksum不同,则覆盖。
  • -filters 排除指定文件
  • -async 异步运行DistCp。Hadoop Job启动后立即退出。
  • -strategy{dynamic|uniformsize}:选择 distcp 使用的策略。默认使用 uniformsize(每个 map 会平衡文件大小)。如果指定 dynamic,则会使用 DynamicInputFormat。

对于其他参数,可以参考官方文档

示例

这里将我用的命令放上来给大家参考下:

1
hadoop distcp -bandwidth 20 -m 1 -overwrite -async -strategy dynamic webhdfs://master:50070/user/hive/db_name_source/ hdfs://slave3/user/hive/db_name_target/

因为这两个集群之间没有专线,和其他爬虫部门共用百兆带宽,所以带宽不能太高,map数量为1是因为很少有数据单个目录超过256M,所以没必要设置的太多,设置太多反而会造成Timeout等错误。