1.需求
我们项目中需要复制一个大文件,最开始使用的是hadoop cp命令,但是随着文件越来越大,拷贝的时间也水涨船高。下面进行hadoop cp与hadoop distcp拷贝时间上的一个对比。我们将11.9G的文件从data_group/adv/day=20210526下所有文件复制到tmp/data_group/adv/day=20210526/文件下
1.1 查看文件大小
hadoop fs -du -s -h data_group/adv/day=20210526
11.9 G data_group/adv/day=20210526
1.2 复制
hadoop distcp data_group/adv/day=20210526 \
tmp/data_group/adv/day=20210526
hadoop fs -cp data_group/adv/day=20210526 \
tmp/data_group/adv/day=20210526
1.3 对比
使用distcp命令 仅耗时1分钟;而hadoop cp命令耗时14分钟
2. 概述
DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具。 它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成。 它把文件和目录的列表作为map任务的输入,每个任务会完成源列表中部分文件的拷贝。 由于使用了Map/Reduce方法,这个工具在语义和执行上都会有特殊的地方。
2.1 distcp命令 输出
17/01/19 14:30:07 INFO tools.DistCp: Input Options: DistCpOptions{atomicCommit=false, syncFolder=false, deleteMissing=false, ignoreFailures=false, maxMaps=20, sslConfigurationFile='null', copyStrategy='uniformsize', sourceFileListing=null, sourcePaths=[data_group/adv/day=20210526], targetPath=tmp/data_group/adv/day=20210526}
...
17/01/19 14:30:17 INFO mapreduce.Job: map 0% reduce 0%
17/01/19 14:30:29 INFO mapreduce.Job: map 6% reduce 0%
17/01/19 14:30:34 INFO mapreduce.Job: map 41% reduce 0%
17/01/19 14:30:35 INFO mapreduce.Job: map 94% reduce 0%
17/01/19 14:30:36 INFO mapreduce.Job: map 100% reduce 0%
17/01/19 14:31:34 INFO mapreduce.Job: Job job_1472052053889_8081193 completed successfully
17/01/19 14:31:34 INFO mapreduce.Job: Counters: 30
File System Counters
FILE: Number of bytes read=0
FILE: Number of bytes written=1501420
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=12753350866
HDFS: Number of bytes written=12753339159
HDFS: Number of read operations=321
HDFS: Number of large read operations=0
HDFS: Number of write operations=69
Job Counters
Launched map tasks=17
Other local map tasks=17
Total time spent by all maps in occupied slots (ms)=485825
Total time spent by all reduces in occupied slots (ms)=0
Map-Reduce Framework
Map input records=17
Map output records=0
Input split bytes=2414
Spilled Records=0
Failed Shuffles=0
Merged Map outputs=0
GC time elapsed (ms)=1634
CPU time spent (ms)=156620
Physical memory (bytes) snapshot=5716221952
Virtual memory (bytes) snapshot=32341671936
Total committed heap usage (bytes)=12159811584
File Input Format Counters
Bytes Read=9293
File Output Format Counters
Bytes Written=0
org.apache.hadoop.tools.mapred.CopyMapper$Counter
BYTESCOPIED=12753339159
BYTESEXPECTED=12753339159
COPY=17
是不是很熟悉,这就是我们经常看见到的MapReduce任务的输出信息,这从侧面说明了Distcp使用Map/Reduce实现。
3. 使用方法
3.1 集群间拷贝
DistCp最常用在集群之间的拷贝:
hadoop distcp hdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo
这条命令会把nn1集群的/foo/bar目录下的所有文件以及bar本身目录(默认情况下)存储到一个临时文件中,这些文件内容的拷贝工作被分配给多个map任务, 然后每个TaskTracker分别执行从nn1到nn2的拷贝操作。注意DistCp使用绝对路径进行操作。
3.2 集群内部拷贝
DistCp也可以集群内部之间的拷贝:
hadoop distcp tmp/data_group/test/a tmp/data_group/test/target
这条命令会把本集群tmp/data_group/test/a目录本身以及a目录下的所有文件拷贝到target目录下,原理同集群之间的拷贝一样。
备注
hadoop distcp tmp/data_group/test/a
tmp/data_group/test/target
上述命令默认情况下是复制a目录以及a目录下所有文件到target目录下:
hadoop fs -ls -R tmp/data_group/test/target/
tmp/data_group/test/target/aa
tmp/data_group/test/target/aa/aa.txt
tmp/data_group/test/target/aa/ab.txt
而有时我们的需求是复制a目录下的所有文件而不包含a目录,这时可以后面介绍的-update参数:
hadoop distcp -update tmp/data_group/test/aa tmp/data_group/test/target
...
hadoop fs -ls -R tmp/data_group/test/target/
tmp/data_group/test/target/aa/aa.txt
tmp/data_group/test/target/aa/ab.txt