hadoop distcp命令使用指导
HDFS distcp命令使用指导
1 背景介绍
DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具。
它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成。
它把文件和目录的列表作为map任务的输入,每个任务会完成源列表中部分文件的拷贝。
以下说明过程中,都使用了默认文件系统,如果需要跨集群拷贝数据,需要将源端或者目标端的路径改成对应的文件系统路径,例如:obs://obs-xxx/xxx或者hdfs://<Active NameNode IP>:<NameNode RPC Port>/xxx/xxx
2 使用方法
2.1 普通用法
hadoop distcp /tmp/source /tmp/target
从/tmp/source拷贝所有文件/文件夹到/tmp/target目录,遇到以下情况的处理方式:
- source非空,target不存在:source所有内容都被拷贝到target
- source非空,target已存在:target原内容不变,source所有内容都被拷贝到target/source下面
2.2 更新操作
hadoop distcp -update -append /tmp/source /tmp/target
从/tmp/source更新所有文件/文件夹到/tmp/target目录,遇到以下情况的处理方式:
- source非空,target不存在:source所有内容都被拷贝到target
- source非空,target已存在,但是内容完全不一致:target原内容不变,source所有内容都被拷贝到target
- source非空,target已存在,但是内容完全一致:target文件不变,所有文件拷贝操作全部跳过
- source非空,target已存在,但是部分文件不一致:
- 如果两边文件不一致,则会以source里面的文件为准覆盖target的同名文件
- 如果source存在,而target不存在,则会将文件复制到target中
- 如果target存在,而source不存在,则会保留文件。
- 其余所有相同的文件全部跳过拷贝操作
2.3 覆盖操作
hadoop distcp -overwrite /tmp/source /tmp/target
从/tmp/source拷贝所有文件/文件夹到/tmp/target目录,遇到以下情况的处理方式:
- source非空,target不存在:source所有内容都被拷贝到target
- source非空,target已存在,但是内容完全不一致:target原内容不变,source所有内容都被拷贝到target
- source非空,target已存在,但是内容完全一致:target文件不变,所有文件拷贝操作全部覆盖
- source非空,target已存在,但是部分文件不一致:
- 如果两边文件不一致,则会以source里面的文件为准覆盖target的同名文件
- 如果source存在,而target不存在,则会将文件复制到target中
- 如果target存在,而source不存在,则会保留文件。
- 其余所有相同的文件全部覆盖拷贝操作
overwrite和update的主要区别在于对于相同文件的处理,是覆盖还是跳过。
3 优化方式
3.1 调整map数量
hadoop distcp -m 5 /tmp/source /tmp/target
一般情况下distcp任务会根据文件情况自动分配map数量,但是某些时候这个map数量设置不符合实际使用场景,例如map数量太多,占用太多资源;或者map数量太少导致数据拷贝太慢等情况。
例如:当前集群或者使用队列的资源只能同时启动15个map,而默认生成的map数量是20个,这样运行起来的时候就会发现有5个map变成第二批次才被执行,导致任务执行时间被延长。如果这个时候我们手动设置map数量为15(-m 15)就能保证资源一直被充分利用,虽然单个map的运行时间变长了,但是整个任务的时间反而减少了。
20个map:
12个map:
3.2 动态优化
使用更新操作的时候,有时候可能会遇到,部分map执行只有几秒钟,而另一部分则花费了几分钟,类似于数据倾斜。
例如:
从日志上看,主要区别在于跳过的文件数量。
运行时间短的任务统计(map任务运行日志最后会打印):
运行时间长的任务统计:
如果有更大数据量的差异存在,这个执行时间可能会相差更多。因此需要调整distcp任务的分配逻辑。
distcp任务划分规则是根据文件大小,尽量让任务的拷贝数据平均分配,默认分配任务是静态的(UniformSizeInputFormat)。但是在更新模式下会发现有些map任务需要拷贝的文件在目标端已经存在,不需要再操作,因此跳过,如果这样的操作较多,就会出现这个map任务明显比其他任务运行更快。
遇到这种情况,我们可以修改为动态分配任务来优化(DynamicInputFormat)。
hadoop distcp -strategy dynamic -update -append /tmp/source /tmp/target
优化之前:
优化之后:
3.3 大文件拷贝优化
使用distcp拷贝有大文件的时候会遇到一个比较麻烦的问题,就是一个大文件只会被一个map任务进行拷贝,这样就会导致任务很慢。
hdfs内部存放数据的方式为block的方式,因此优化方式为对存在有多个block的文件可以并发拷贝。
hadoop distcp -blocksperchunk 4 /tmp/input /tmp/output2
此方法使用的时候有部分限制:
源文件系统需要实现getBlockLocations方法,目标文件系统需要实现concat方法。
因为OBS文件系统未实现concat方法,无法使用此优化措施。
- 点赞
- 收藏
- 关注作者
评论(0)