Hadoop distcp命令(一)
Hadoop distcp命令(二)
DistCp的结构
新版的DistCp
可以分为以下几个部分:
- DistCp Driver
- Copy-listing generator
- Input-formats 和 Map-Reduce components
(1) DistCp Driver
DistCp Driver部分的职责是:
- 解析
DistCp
命令行中的参数,例如:- OptionsParser (选项解析器)
- DistCpOptionsSwitch (DistCp选项开关)
- 将命令行参数整合到特定的
DistCpOption
对象中并且初始化DistCp
。这些参数包括:- 源路径
- 目标路径
- 复制选项(例如:是否在复制的时候更新、复写以及要保留的文件属性等等)
- 通过以下方式编排复制选项:
- 调用
copy-listing-generator
来产生需要被复制的文件列表 - 设置并启动
Hadoop
的Map-Reduce
任务来执行复制。 - 根据这些选项,可以直接返回
Hadoop MR Job
的句柄,或者等待直到完成。
- 调用
参数解析器只在命令行或者调用DistCp::run()
方法时运行。也可以通过编程的方式使用DistCp
,只要创建DistCpOption
对象,并适时的初始化该对象即可。
(2) Copy-listing Generator
copy-listing-generator
用来负责产生需要被复制的文件和目录的列表。他们检查源路径中的内容(文件目录还有通配符),并且把所有需要复制的路径记录到SequenceFile
序列文件中,以供DistCp
的Hadoop Job
使用。该模块中主要的类包括:
-
CopyListing:
该接口应该被所有copy-listing-generator实现类实现。同时也提供了具体
CopyListing
实现的工厂方法。 -
SimpleCopyListing:
是
CopyListing
的一个实现类,可以接受多个源路径,然后递归的列出每个目录下面所有的文件和目录用来复制。 -
globbedCopyListing:
CopyListing
的另一个实现,支持在源路径中使用通配符。 -
FileBaedCopyListing:
CopyListing
的一个实现,从一个指定的文件中读取源路径列表。
根据在DistCpPotions
中是否指定了源文件列表,source-listing
按以下两种不同的方式产生:
- 如果没有指定
source-file-list
源文件列表,就是使用GlobbedCopyListing
。此时所有的通配符都会被扩展,然后所有的扩展都会被转发到SimpleCopyListing
,通过对每个路径向下递归,依次建立listing。 - 如果指定了
source-file-list
,就使用FileBasedCopyListing
。从指定的文件中读取源路径,然后将其转发到GlobbedCopyListing
。然后按上面所说的构建列表。
此外,也可以通过实现CopyListing
接口定义自己的复制列表的方法。DistCp
与传统的DistCp
不同的地方在于如何考虑复制时的路径。
传统的实现只列出明确需要被复制的目标路径,如果目标目录下已经有文件了(并且没有指定-overwrite
参数),之后的MapReduce
任务就不会继续考虑这个文件了。在设置过程中(即MapReduce
任务之前)确定此设置包括文件大小和检查数比较等,是一件比较费时间的事情。
新版的DistCp
将这些检查推迟到MapReduce
任务中,因此可以节省设置时间。因为这些检查被并行的分布在各个map任务中,因此性能得到了很大的提升。
(3) InputFormats and MapReduce Components
InputFormats
和MapReduce
部分主要负责实际的文件拷贝工作,由copy-list
生成器产生的列表文件就在拷贝过程执行时起作用。这里几个值得注意的类包括:
-
UniformSizeInputFormat:
该类实现了
org.apache.hadoop.mapreduce.InputFormat
接口,InputFormat
为传统的DistCp
的每个map任务的负载进行均衡UniformSizeInputFormat
的目的是让每个map
任务负责的拷贝任务的文件字节数大致相同。同时文件列表被适当的分成路径组,这样使得每个InputSplit
中文件数的总和与其他map
几乎相等。这种切分并不总是完美的,但是这种分解的方式让设置时间变短了。 -
DynamicInputFormat 和 DynamicRecordReader:
DynamicInputFormat
实现了org.apache.hadoop.mapreduce.InputFormat
,是DistCp
的新增功能。文件列表被切分为不同的块文件,块文件的数量是Hadoop
任务中请求的map
个数的倍数。在任务提交之前,每一个map
任务都分配了一个块文件(通过把块文件更名为任务id的方式)。使用DynamicRecordReader
从每个块中读取路径,并在CopyMapper
中处理。当快中的所有路径都被处理之后,当前块就会被删除,然后获取新的块。这个过程一致持续到所有的数据块都被处理完为止。这种动态的方式可以让速度较快的map任务比速度较慢的map任务处理更多的路径,因此DistCp
任务的速度就会提升很多。 -
CopyMapper:
这个类实现了物理的文件拷贝。根据输入选项检查输入路径(在
Job Configuration
指定)来决定一个文件是否需要拷贝。只有当一下条件中任意条件满足就执行拷贝。- 目标目录下不存在同名文件
- 目标目录下存在同名文件,但是文件长度不同
- 目标目录下存在同名文件,但是有不同的校验和,并且没有使用-skipcrccheck参数
- 目标目录下存在同名文件,但是使用-overwrite参数
- 目标目录下存在同名文件,但是块大小不同,同时块大小需要被保留。
-
CopyCommitter:
这个类负责DistCp任务的提交,包括:
- 保留目录权限(如果在选项中指定了)
- 清理临时文件、工作目录等等。
这是鄙人的公众号,会第一时间在上面更新与大数据相关的文章。