hadoop之distcp(分布式拷贝)
概述
distcp(分布式拷贝)是⽤于⼤规模集内部和集之间拷贝的⼯具。它使⽤Map/Reduce实现⽂件分发,错误处理和恢复,以及报告⽣成。它把⽂件和⽬录的列表作为map任务的输⼊,每个任务会完成源列表中部分⽂件的拷贝。由于使⽤了Map/Reduce⽅法,这个⼯具在语义和执⾏上都会有特殊的地⽅。这篇⽂档会为常⽤distcp操作提供指南并阐述它的⼯作模型。
基本使⽤⽅法
distcp最常⽤在集之间的拷贝:
hadoop distcp hdfs://master1:8020/foo/bar hdfs://master2:8020/bar/foo
这条命令会把master集的/foo/bar⽬录下的所有⽂件或⽬录名展开并存储到⼀个临时⽂件中,这些⽂件内容的拷贝⼯作被分配给多个map任务,然后每个TaskTracker分别执⾏从master1到master2的拷贝操作。注意distcp使⽤绝对路径进⾏操作。
命令⾏中可以指定多个源⽬录:
hadoop distcp hdfs://master1:8020/foo/a hdfs://master1:8020/foo/b hdfs://master2:8020/bar/foo
或者使⽤-f选项,从⽂件⾥获得多个源:
hadoop distcp -f hdfs://master1:8020/srclist hdfs://master2:8020/bar/foo
其中srclist 的内容是
hdfs://master1:8020/foo/a
hdfs://master1:8020/foo/b
当从多个源拷贝时,如果两个源冲突,distcp会停⽌拷贝并提⽰出错信息,如果在⽬的位置发⽣冲突,会根据选项设置解决。默认情况会跳过已经存在的⽬标⽂件(⽐如不⽤源⽂件做替换操作)。每次操作结束时都会报告跳过的⽂件数⽬,但是如果某些拷贝操作失败了,但在之后的尝试成功了,那么报告的信息可能不够精确。
每个TaskTracker必须都能够与源端和⽬的端⽂件系统进⾏访问和交互。对于HDFS来说,源和⽬的端要运⾏相同版本的协议或者使⽤向下兼容的协议。
拷贝完成后,建议⽣成源端和⽬的端⽂件的列表,并交叉检查,来确认拷贝真正成功。因为distcp使⽤Map/Reduce和⽂件系统API进⾏操作,所以这三者或它们之间有任何问题都会影响拷贝操作。⼀些distcp命令的成功执⾏可以通过再次执⾏带-update参数的该命令来完成,但⽤户在如此操作之前应该对该命令的语法很熟悉。
值得注意的是,当另⼀个客户端同时在向源⽂件写⼊时,拷贝很有可能会失败。尝试覆盖HDFS上正在被写⼊的⽂件的操作也会失败。如果⼀个源⽂件在拷贝之前被移动或删除了,拷贝失败同时输出异常 FileNotFoundException
选项
选项索引
标识描述备注
-p[rbugp]Preserve
r: replication
number
b: block size
u: user
g: group
p: permission
修改次数不会被保留。并且当指定 -update 时,更新的状态不会被同步,除⾮⽂件⼤⼩不同(⽐如⽂件被
重新创建)。
-i忽略失败就像在附录中提到的,这个选项会⽐默认情况提供关于拷贝的更精确的统计,同时它还将保留失败拷贝操作的⽇志,这些⽇志信息可以⽤于调试。最后,如果⼀个map失败了,但并没完成所有分块任务的尝试,这不会导致整个作业的失败。
-log <logdir>记录⽇志到
<logdir>DistCp为每个⽂件的每次尝试拷贝操作都记录⽇志,并把⽇志作为map的输出。如果⼀个map失败了,当重新执⾏时这个⽇志不会被保留。
-m
<num_maps>同时拷贝的最⼤
数⽬
指定了拷贝数据时map的数⽬。请注意并不是map数越多吞吐量越⼤。
-overwrite覆盖⽬标如果⼀个map失败并且没有使⽤-i选项,不仅仅那些拷贝失败的⽂件,这个分块任务中的所有⽂件都会被重新拷贝。就像提到的,它会改变⽣成⽬标路径的语义,所以⽤户要⼩⼼使⽤这个选项。
如果源和⽬标的
像之前提到的,这不是"同步"操作。执⾏覆盖的唯⼀标准是源⽂件和⽬标⽂件⼤⼩是否相同;如果不同,
-update 如果源和⽬标的
⼤⼩不⼀样则进
⾏覆盖
像之前提到的,这不是"同步"操作。执⾏覆盖的唯⼀标准是源⽂件和⽬标⽂件⼤⼩是否相同;如果不同,
则源⽂件替换⽬标⽂件。像提到的,它也改变⽣成⽬标路径的语义,⽤户使⽤要⼩⼼。
-f <urilist_uri>使⽤<urilist_uri>
作为源⽂件列表
这等价于把所有⽂件名列在命令⾏中。 urilist_uri 列表应该是完整合法的URI。
更新和覆盖
这⾥给出⼀些 -update和 -overwrite的例⼦。考虑⼀个从/foo/a 和 /foo/b 到 /bar/foo的拷贝,源路径包括:
hdfs://master1:8020/foo/a
hdfs://master1:8020/foo/a/aa
hdfs://master1:8020/foo/a/ab
hdfs://master1:8020/foo/b
hdfs://master1:8020/foo/b/ba
hadoop分布式集搭建hdfs://master1:8020/foo/b/ab
如果没设置-update或 -overwrite选项,那么两个源都会映射到⽬标端的 /bar/foo/ab。如果设置了这两个选项,每个源⽬录的内容都会和⽬标⽬录的内容做⽐较。distcp碰到这类冲突的情况会终⽌操作并退出。
默认情况下,/bar/foo/a 和 /bar/foo/b ⽬录都会被创建,所以并不会有冲突。
现在考虑⼀个使⽤-update合法的操作:
distcp -update hdfs://master1:8020/foo/a \
hdfs://master1:8020/foo/b \
hdfs://master2:8020/bar
其中源路径/⼤⼩:
hdfs://master1:8020/foo/a
hdfs://master1:8020/foo/a/aa 32
hdfs://master1:8020/foo/a/ab 32
hdfs://master1:8020/foo/b
hdfs://master1:8020/foo/b/ba 64
hdfs://master1:8020/foo/b/bb 32
和⽬的路径/⼤⼩:
hdfs://master2:8020/bar
hdfs://master2:8020/bar/aa 32
hdfs://master2:8020/bar/ba 32
hdfs://master2:8020/bar/bb 64
会产⽣:
hdfs://master2:8020/bar
hdfs://master2:8020/bar/aa 32
hdfs://master2:8020/bar/ab 32
hdfs://master2:8020/bar/ba 64
hdfs://master2:8020/bar/bb 32
只有master2的aa⽂件没有被覆盖。如果指定了 -overwrite选项,所有⽂件都会被覆盖。
附录
Map数⽬
distcp会尝试着均分需要拷贝的内容,这样每个map拷贝差不多相等⼤⼩的内容。但因为⽂件是最⼩的拷贝粒度,所以配置增加同时拷贝(如map)的数⽬不⼀定会增加实际同时拷贝的数⽬以及总吞吐量。
如果没使⽤-m选项,distcp会尝试在调度⼯作时指定map的数⽬为 min (total_bytes / bytes.per.map, 20 * num_task_trackers),其
中bytes.per.map默认是256MB。
建议对于长时间运⾏或定期运⾏的作业,根据源和⽬标集⼤⼩、拷贝数量⼤⼩以及带宽调整map的数⽬。
hadoop distcp -Ddistcp.bytes.per.map=1073741824 -Ddfs.client.socket-timeout=240000000 -t.timeout=40000000 -i -update hdfs://master1:8020/foo/a hdfs://master1:8020/foo/b hdfs://master2:8020/bar/foo
不同HDFS版本间的拷贝
对于不同Hadoop版本间的拷贝,⽤户应该使⽤HftpFileSystem。这是⼀个只读⽂件系统,所以distcp必须运⾏在⽬标端集上(更确切的说
是在能够写⼊⽬标集的TaskTracker上)。源的格式是 hftp://<dfs.http.address>/<path> (默认情况dfs.http.address是<namenode>:50070)。
Map/Reduce和副效应
像前⾯提到的,map拷贝输⼊⽂件失败时,会带来⼀些副效应。
除⾮使⽤了-i,任务产⽣的⽇志会被新的尝试替换掉。
除⾮使⽤了-overwrite,⽂件被之前的map成功拷贝后当⼜⼀次执⾏拷贝时会被标记为 "被忽略"。
如果map失败了mapred.map.max.attempts次,剩下的map任务会被终⽌(除⾮使⽤了-i)。
如果ution被设置为 final和true,则拷贝的结果是未定义的。
source:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论