集群间数据迁移工具distcp

最近公司集群切换,需要将老集群中的数据迁移到新集群上,了解到了distcp这个工具。借助它很好的完成了迁移任务。
基础用法如下:

    hadoop distcp hdfs://cluster1:9000/stat hdfs://cluster2:9000/

这里就是把cluster1中的stat拷贝到cluster2中,这里需要注意源路径和目标路径均要写绝对路径。
另外,如果源路径较多,可以将原路径写到一个文本中,然后通过:

hadoop distcp -f hdfs://nn1:8020/srclist hdfs://nn2:8020/destination

其中srclist中存的就是多个原路径的绝对路径。
以上只是最简单的用法,具体还有一些相关参数可以进行设置,如:

标识    描述                      备注
-p      [rbugp]                 Preserve
        r:replication number
        b: block size
        u: user
        g: group
        p: permission
-i      忽略失败             这个选项会比默认情况提供关于拷贝的更精确的统计,
-log    <logdir>                记录日志到 <logdir>
-m      <num_maps>      指定了拷贝数据时map的数目。请注意并不是map数越多吞吐量越大。
-overwrite 覆盖目标      如果目标路径有内容会直接覆盖。
-update 如果源和目标的大小不一样则进行覆盖   
-f     <urilist_uri>    用<urilist_uri> 作为源文件列表  这等价于把所有文件名列在命令行中。 urilist_uri 列表应该是完整合法的URI

由于官网介绍有说道,在应用执行迁移数据过程中,如果有客户端同时在往源文件中写数据,则很有可能会导致应用执行失败,而我们的集群环境中源文件就有可能会在拷贝时有客户端往hdfs上写数据,对此如果拷贝的时候需要自己选择好最小拷贝目录粒度,这样可以防止出现以上问题,我们线上数据是按天来分割的,一般只会修改当天数据,所以我会对某类一级目录下,按天划分为一个个小的任务目录,对每一天的数据执行distcp,从而避免失败。
本人是使用脚本实现的,我的脚本如下:

#!/bin/sh
# 由于distcp在迁移时,如果有客户端在往源路径下写入数据,很可能会导致数据迁移失败,为此要对迁移的数据进行二级目录(时间)级别迁移。
# 入参就是根目录“/”下的文件名  源:hdfs://cluster1:9000/$1/subxxx  目标:hdfs://cluster2:9000/$1
# 脚本在225这台老的NN上执行
orig=$1   #orig=/stat
filter=$2
sourcePath=  #sourcePath=hdfs://cluster1:9000/stat/20180712
destPath=    #destPath=hdfs://cluster2:9000/stat
destRootPath=

#以防拷贝中途出现主备切换的情况,找到active的namenode
getSourcePath(){
    statenn1=`hdfs haadmin -getServiceState nn1`
    statenn2=`hdfs haadmin -getServiceState nn2`
    if [ $statenn1 = "active" ];then
        sourcePath="hdfs://hdfsname:9000$1"
    elif [ $statenn2 = "active" ];then
        sourcePath="hdfs://cluster1:9000$1"
    else
        echo "nn1 state is $statenn1 and nn2 state is $statenn2, no active namenode, please check old hadoop cluster!"
        exit 1
    fi
}

getDestPath(){
    hdfsBin=/home/mmtrix/Application/Gosun/enterprise/hadoop/hadoop-2.6.0-cdh5.4.1/bin/hdfs
    newStatenn1=`ssh xxx.xxx.xxx.xxx $hdfsBin haadmin -getServiceState nn1`
    newStatenn2=`ssh xxx.xxx.xxx.xxx $hdfsBin haadmin -getServiceState nn2`
    if [ $newStatenn1 = "active" ];then
        destPath="hdfs://cluster2:9000$1"
        destRootPath="hdfs://cluster2:9000"
    elif [ $newStatenn2 = "active" ];then
        destPath="hdfs://xxx:9000$1"
        destRootPath="hdfs://xxx:9000"
    else
        echo "nn1 state is $statenn1 and nn2 state is $statenn2, no active namenode, please check new hadoop cluster!"
        exit 1
    fi
}

oldifs="$IFS"
IFS=$'\n'
for line in `hadoop fs -du $orig|grep $filter`
do
    subPath=`echo $line|awk '{print $3}'` #subPath=/stat/20180712
    fileName=`echo $subPath|awk -F "/" '{print $NF}'` #fileName=20180712
    getSourcePath $subPath
    getDestPath $orig
    echo "from $sourcePath to $destPath"

    #-update参数会校验源路径下文件和目标处文件大小是否一样,不一样就会覆盖,
    #一样就会跳过执行,这样如果第二次执行时可以跳过已经拷贝完成的内容 -need test!
    hadoop distcp -m 300 $sourcePath $destPath

    #对迁移完的文件进行校验,比较大小是否一样
    localSize=`hadoop fs -du $orig|grep $fileName`

    remoteSize=`hadoop fs -du $destRootPath$orig|grep $fileName`
    if [ $localSize -eq $remoteSize ];then
        echo "$subPath validate OK!"
    else
        echo "$subPath copy error!"
    fi
done
IFS="$oldifs"

参考文献:
https://www.cnblogs.com/felixzh/p/5920153.html -key
https://www.cnblogs.com/charlist/p/7122418.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值