Hadoop 文档

General

Common

HDFS

MapReduce

MapReduce REST APIs

YARN

YARN REST APIs

YARN Service

Submarine

Hadoop Compatible File Systems

Auth

Tools

Reference

Configuration



总览

DistCp(分布式副本)是用于大型集群间/集群内复制的工具。它使用MapReduce来实现其分发,错误处理和恢复以及报告。它将文件和目录的列表扩展为映射任务的输入,每个任务都会复制源列表中指定的文件分区。

[DistCp以前的实现](http://hadoop.apache.org/docs/r1.2.1/distcp.html)在用法,可扩展性和性能上都有其独特之处。DistCp重构的目的是解决这些缺陷,使其能够以编程方式使用和扩展。引入了新的范例以改善运行时和设置性能,同时将默认行为保留为旧行为。

本文档旨在描述新的DistCp的设计,其新功能,它们的最佳使用以及与传统实现的任何偏离。

用法

基本用法

DistCp的最常见调用是集群间副本:

bash $ hadoop distcp hdfs:// nn1:8020 / foo / bar \
hdfs:// nn2:8020 / bar / foo

这会将nn1上/ foo / bar下的命名空间扩展为一个临时文件,在一系列映射任务中对其内容进行分区,并在每个NodeManager上从nn1nn2启动一个副本。

您还可以在命令行上指定多个源目录:

bash $ hadoop distcp hdfs:// nn1:8020 / foo / a \
hdfs:// nn1:8020 / foo / b \
hdfs:// nn2:8020 / bar / foo

或者,等效地,使用-f选项从文件中获取:

bash $ hadoop distcp -f hdfs:// nn1:8020 / srclist \
hdfs:// nn2:8020 / bar / foo

srclist包含在哪里

hdfs:// nn1:8020 / foo / a
hdfs:// nn1:8020 / foo / b

从多个源进行复制时,如果两个源发生冲突,DistCp将中止复制并显示一条错误消息,但是根据指定的选项解决了目标上的冲突。默认情况下,将跳过目标位置已存在的文件(即不替换为源文件)。在每个作业结束时都会报告跳过的文件计数,但是如果复印机对其文件的某些子集失败了,但是在以后的尝试中成功了,这可能是不准确的。

每个NodeManager都可以访问源文件系统和目标文件系统并与之通信很重要。对于HDFS,源和目标都必须运行相同版本的协议或使用向后兼容的协议。请参见[在版本之间复制](#Copying_Between_Versions_of_HDFS)。

复制后,建议生成并交叉检查源和目标列表,以验证复制是否真正成功。由于DistCp同时使用Map / Reduce和FileSystem API,因此这三个文件中的任何一个或两个之间的问题都可能对副本造成不利影响且无提示。某些在启用-update的情况下成功运行以执行第二遍,但是在尝试执行此操作之前,用户应该熟悉其语义。

还值得注意的是,如果另一个客户端仍在写入源文件,则复制可能会失败。在HDFS上尝试覆盖正在目标位置写入的文件也将失败。如果在复制之前(移出)了源文件,则复制将失败,并带有FileNotFoundException

有关DistCp中所有可用选项的信息,请参考详细的命令行参考。

更新和覆盖

-update用于从源复制目标上不存在或与目标版本不同的文件。-overwrite覆盖目标上存在的目标文件。

Update和Overwrite选项值得特别注意,因为它们对源路径的处理与默认设置有很大的不同。考虑从/ source / first // source / second // target /的副本,其中源路径具有以下内容:

hdfs:// nn1:8020 / source / first / 1
hdfs:// nn1:8020 / source / first / 2
hdfs:// nn1:8020 / source / second / 10
hdfs:// nn1:8020 / source / second / 20

在不使用-update-overwrite的情况下调用DistCp时,DistCp的默认值将在/ target下创建目录first /second /。从而:

distcp hdfs:// nn1:8020 / source /第一个hdfs:// nn1:8020 / source / second hdfs:// nn2:8020 / target

将在/ target中产生以下内容:

hdfs:// nn2:8020 / target / first / 1
hdfs:// nn2:8020 / target / first / 2
hdfs:// nn2:8020 / target / second / 10
hdfs:// nn2:8020 / target / second / 20

当指定-update-overwrite时,源目录的内容将复制到目标,而不是源目录本身。从而:

distcp-更新hdfs:// nn1:8020 / source /第一个hdfs:// nn1:8020 / source / second hdfs:// nn2:8020 / target

将在/ target中产生以下内容:

hdfs:// nn2:8020 / target / 1
hdfs:// nn2:8020 / target / 2
hdfs:// nn2:8020 / target / 10
hdfs:// nn2:8020 / target / 20

通过扩展,如果两个源文件夹都包含一个具有相同名称(例如0)的文件,则两个源都将一个条目映射到目标位置的/ target / 0。DistCp将放弃,而不是允许这种冲突。

现在,考虑以下复制操作:

distcp hdfs:// nn1:8020 / source /第一个hdfs:// nn1:8020 / source / second hdfs:// nn2:8020 / target

带有来源/尺寸:

hdfs:// nn1:8020 / source / first / 1 32
hdfs:// nn1:8020 / source / first / 2 32
hdfs:// nn1:8020 / source / second / 10 64
hdfs:// nn1:8020 / source / second / 20 32

和目的地/大小:

hdfs:// nn2:8020 / target / 1 32
hdfs:// nn2:8020 / target / 10 32
hdfs:// nn2:8020 / target / 20 64

将影响:

hdfs:// nn2:8020 / target / 1 32
hdfs:// nn2:8020 / target / 2 32
hdfs:// nn2:8020 / target / 10 64
hdfs:// nn2:8020 / target / 20 32

因为文件长度和内容匹配,所以跳过1。复制2,因为它在目标位置不存在。由于内容与源不匹配,因此将覆盖1020

如果使用-update,则跳过1,因为文件长度和内容匹配。复制2,因为它在目标位置不存在。由于内容与源不匹配,因此将覆盖1020。但是,如果另外使用-append,则仅覆盖10(源长度小于目标长度),并在文件更改后附加20(如果文件匹配目标的原始长度)。

如果使用-overwrite,则1也将被覆盖。

同步

-diff选项使用快照差异将文件从源集群同步到目标集群。它复制,重命名和删除快照差异列表中的文件。

使用-diff选项时,必须包括-update选项。

目前,大多数云提供商在同步方面都无法很好地工作。

用法:

hadoop distcp -update -diff <from_snapshot> <to_snapshot> <源> <目标>

例:

hadoop distcp -update -diff snap1 snap2 / src / / dst /

上面的命令将/ src /中的更改从快照snap1更改为snap2(即,快照从snap1更改为snap2)更改为/ dst /。显然,它需要/ src /同时具有快照snap1snap2。但是目标 / dst /也必须具有与<from_snapshot>相同名称的快照,在这种情况下为snap1。自snap1以来,目标/ dst /不应具有新文件操作(创建,重命名,删除)。请注意,此命令完成后,将创建一个新的快照snap2。不会在/ dst /创建。

使用-diff选项需要-update

例如,在/ SRC /,如果1.txt的加入和2.txt被创建后删除snap1和创建的之前snap2,上面的命令将复制的1.txt/ SRC // DST /和删除2来自/ dst /的.txt

同步行为将通过以下实验进行详细说明。

实验1:同步两个相邻快照的差异

我们开始之前的一些准备工作。

#创建源目录和目标目录
hdfs dfs -mkdir / src / / dst /
#允许源快照
hdfs dfsadmin -allowSnapshot / src /
#创建一个快照(空)
hdfs dfs -createSnapshot / src / snap1
#允许在目标上快照
hdfs dfsadmin -allowSnapshot / dst /
#创建一个具有相同名称的from_snapshot
hdfs dfs -createSnapshot / dst / snap1

#将一个文本文件放在/ src /下
echo“这是第一个文本文件。” > 1.txt
hdfs dfs -put 1.txt / src /
#创建第二个快照
hdfs dfs -createSnapshot / src / snap2

#将另一个文本文件放在/ src /下
echo“这是第二个文本文件。” > 2.txt
hdfs dfs -put 2.txt / src /
#创建第三个快照
hdfs dfs -createSnapshot / src / snap3

然后我们运行distcp sync:

hadoop distcp -update -diff snap1 snap2 / src / / dst /

上面的命令应该成功。1.txt将从/ src /复制到/ dst /中。同样,需要-update选项。

如果再次运行相同的命令,将收到DistCp同步失败的异常,因为目标从snap1开始添加了一个新文件1.txt。话虽如此,如果我们从/ dst /中手动删除1.txt并运行同步,该命令将成功。

实验2:同步两个不相邻快照的差异

首先从实验1进行清理。

hdfs dfs -rm -skip垃圾箱/dst/1.txt

运行同步命令,请注意<to_snapshot> 已从实验1中的snap2更改为snap3

hadoop distcp -update -diff snap1 snap3 / src / / dst /

双方的1.txt2.txt将被复制到/ DST /

实验3:同步文件删除操作

从实验2的结尾继续:

hdfs dfs -rm -skip垃圾箱/dst/2.txt
#在目标位置创建snap2,其中包含1.txt
hdfs dfs -createSnapshot / dst / snap2

#从源代码中删除1.txt
hdfs dfs -rm -skip垃圾桶/src/1.txt
#在源代码处创建snap4,仅包含2.txt
hdfs dfs -createSnapshot / src / snap4

立即运行同步命令:

hadoop distcp -update -diff snap2 snap4 / src / / dst /

复制/ txt /下的2.txt,删除1.txt

请注意,尽管/ src // dst /都具有名称相同的快照snap2,但快照不必具有相同的内容。这意味着,如果/ dst /snap2中1.txt,但它们的内容不同,则1.txt仍将从/ dst /中删除。sync命令不会检查将要删除的文件的内容。它仅遵循<from_snapshot>和<to_snapshot> 之间的快照差异列表。

另外,如果在上述步骤中在/ dst /上创建snap2之前从/ dst /中删除1.txt,以使/ dst /snap2在运行sync命令之前没有1.txt,该命令仍将成功。尝试从不存在的/ dst /中删除1.txt时,它不会引发异常。

原始命名空间扩展属性保留

本部分仅适用于HDFS。

如果目标和所有源路径名都在/.reserved/raw层次结构中,则将保留“原始”名称空间扩展属性。系统将“原始” xattrs用于内部功能,例如加密元数据。只有通过/.reserved/raw层次结构访问时,它们才对用户可见。

仅根据是否提供/.reserved/raw前缀来保留原始xattrs。-p(保留,请参见下文)标志不会影响原始xattrs的保留。

为了防止保留原始xattrs,只需在任何源路径和目标路径上都不使用/.reserved/raw前缀。

如果仅在源路径和目标路径的子集上指定/.reserved/raw前缀,将显示错误并返回非0的退出代码。

命令行选项

描述 笔记
-p [rbugpcaxt] 保留r:复制编号b:块大小u:用户g:组p:权限c:校验和类型a:ACL x:XAttr t:时间戳记 当指定-update时,除非文件大小也不同(即除非重新创建文件),否则状态更新将不会同步。如果指定了-pa,则DistCp还会保留权限,因为ACL是权限的超集。仅当源目录和目标目录均未进行擦除编码时,选项-pr才有效。注意:如果未指定-p选项,则默认情况下将保留块大小。
-一世 忽略故障 如附录中所述,此选项将比默认情况保留有关副本的更准确的统计信息。它还会保留来自失败副本的日志,这对于调试很有用。最后,在尝试所有拆分之前,失败的映射不会导致作业失败。
-log <logdir> 将日志写入<logdir> DistCp保留尝试复制的每个文件的日志作为地图输出。如果映射失败,则重新执行该日志后将不会保留该日志输出。
-v 在“跳过/复制”日志中记录其他信息(路径,大小) 此选项只能与-log选项一起使用。
-m <num_maps> 最大同时复制数 指定要复制数据的地图数。请注意,更多地图不一定能提高吞吐量。
-覆盖 覆盖目的地 如果映射失败并且未指定-i,则将重新复制拆分中的所有文件,不仅是失败的文件。正如用法文档中所讨论的,它也更改了生成目标路径的语义,因此用户应谨慎使用它。
-更新 如果源和目标的大小,块大小或校验和不同,则覆盖 如前所述,这不是“同步”操作。检查的标准是源文件和目标文件的大小,块大小和校验和。如果它们不同,则源文件将替换目标文件。正如用法文档中所讨论的,它也更改了生成目标路径的语义,因此用户应谨慎使用它。
-附加 具有相同名称但长度不同的文件的增量副本 如果源文件的长度大于目标文件的长度,则将比较公共长度部分的校验和。如果校验和匹配,则使用读取和追加功能仅复制差异。-append选项仅与-update一起使用,而没有-skipcrccheck
-f <urilist_uri> 将<urilist_uri>中的列表用作src列表 这等效于在命令行上列出每个源。该urilist_uri名单应该是一个完全合格的URI。
-过滤器 包含模式字符串列表的文件的路径,每行一个字符串,这样,与模式匹配的路径将从副本中排除。 支持由java.util.regex.Pattern指定的正则表达式。
-filelimit <n> 将文件总数限制为<= n 不推荐使用!在新的DistCp中被忽略。
-sizelimit <n> 将总大小限制为<= n个字节 不推荐使用!在新的DistCp中被忽略。
-删除 删除dst中存在的文件,但不删除src中的文件 删除由FS Shell完成。因此,如果启用了废纸will,则将使用它。删除仅适用于更新或覆盖选项。
策略{dynamic | uniformsize} 选择要在DistCp中使用的复制策略。 默认情况下,使用统一大小。(即,地图在每个地图复制的文件的总大小上保持平衡。类似于旧版。)如果指定了“ dynamic”,则使用DynamicInputFormat。(这在“输入格式”下的“体系结构”部分中进行了描述。)
-带宽 指定每个地图的带宽,以MB /秒为单位。 每个映射将被限制为仅消耗指定的带宽。这并不总是准确的。映射会在复制期间限制其带宽消耗,以使使用的带宽趋向于指定值。
-atomic {-tmp <tmp_dir>} 指定原子提交,并带有可选的tmp目录。 -atomic指示DistCp将源数据复制到临时目标位置,然后以原子方式将临时目标移动到最终位置。数据将以完整一致的形式提供给最终目标,或者根本不提供。可选地,-tmp可用于指定tmp-target的位置。如果未指定,则选择默认值。注意: tmp_dir必须在最终目标群集上。
-异步 异步运行DistCp。Hadoop Job启动后立即退出。 记录Hadoop Job-id,以进行跟踪。
-diff <旧快照> <新快照> 在给定的两个快照之间使用快照差异报告来识别源和目标之间的差异,并将差异应用于目标以使其与源同步。 该选项仅对-update选项有效,并且应满足以下条件。
  1. 源文件系统和目标文件系统都必须是DistributedFileSystem。
  2. 已在源FS上创建了两个快照<oldSnapshot><newSnapshot>,并且<oldSnapshot>早于<newSnapshot>
  3. 目标具有相同的快照<oldSnapshot>。自创建<oldSnapshot>以来,未对目标进行任何更改,因此<oldSnapshot>的内容与目标的当前状态相同。目标文件中的所有文件/目录与源文件的<oldSnapshot>相同
-rdiff <newSnapshot> <oldSnapshot> 使用给定的两个快照之间的快照差异报告来确定自从在目标上创建快照<oldSnapshot>以来目标上已更改的内容,然后将差异反向应用于目标,并从源的<oldSnapshot>复制修改后的文件到使目标与<oldSnapshot>相同。 该选项仅对-update选项有效,并且应满足以下条件。
  1. 源文件系统和目标文件系统都必须是DistributedFileSystem。源和目标可以是两个不同的群集/路径,也可以是完全相同的群集/路径。在后一种情况下,将修改的文件从目标的<oldSnapshot>复制到目标的当前状态)。
  2. 在目标FS上已创建两个快照<newSnapshot><oldSnapshot>,并且<oldSnapshot>早于<newSnapshot>自在目标上创建<newSnapshot>以来,未对目标进行任何更改。
  3. 源具有相同的快照<oldSnapshot>,其内容与目标上的<oldSnapshot>相同。目标的<oldSnapshot>中的所有文件/目录与源的<oldSnapshot>相同
-numListstatusThreads 用于构建文件列表的线程数 最多40个线程。
-skipcrccheck 是否在源路径和目标路径之间跳过CRC检查。
-blocksperchunk <blocksperchunk> 每个块的块数。指定后,将文件拆分为多个块以并行复制 如果设置为正值,则块数超过该值的文件将被拆分为<blocksperchunk>块的块,以并行传输,然后在目标位置重新组合。默认情况下,<blocksperchunk>为0,文件将完整传输而不拆分。仅当源文件系统实现getBlockLocations方法并且目标文件系统实现concat方法时,此开关才适用。
-copybuffersize <copybuffersize> 要使用的复制缓冲区的大小。默认情况下,<copybuffersize>设置为8192B
-xtrack <路径> 将有关丢失的源文件的信息保存到指定的路径。 该选项仅对-update选项有效。这是实验性质,不能与-atomic选项一起使用。
-直接 直接写入目标路径 当目标是对象存储时,有助于避免可能非常昂贵的临时文件重命名操作

DistCp的体系结构

新的DistCp的组件可以分为以下几类:

  • DistCp驱动程序
  • 复制清单生成器
  • 输入格式和Map-Reduce组件

DistCp驱动程序

DistCp驱动程序组件负责:

  • 通过以下方式解析在命令行上传递给DistCp命令的参数:

    • OptionsParser,和
    • DistCpOptionsSwitch
  • 将命令参数组合到适当的DistCpOptions对象中,然后初始化DistCp。这些参数包括:

    • 源路径
    • 目标位置
    • 复制选项(例如,是否要进行更新复制,覆盖,保留哪些文件属性等)
  • 通过以下方式协调复制操作:

    • 调用copy-listing-generator创建要复制的文件列表。
    • 设置并启动Hadoop Map-Reduce作业以执行复制。
    • 根据这些选项,可以立即将句柄返回给Hadoop MR Job,或者等待直到完成。

仅从命令行(或如果调用DistCp :: run())执行解析器元素。通过构造DistCpOptions对象并适当地初始化DistCp对象,也可以通过编程方式使用DistCp类。

复制清单生成器

copy-listing-generator类负责创建要从源复制的文件/目录的列表。他们检查源路径的内容(文件/目录,包括通配符),并将所有需要复制的路径记录到SequenceFile中,以供DistCp Hadoop Job使用。此模块中的主要类包括:

  1. CopyListing:任何copy-listing-generator实现都应实现的接口。还提供了用于选择具体CopyListing实现的工厂方法。
  2. SimpleCopyListingCopyListing的一种实现,它接受多个源路径(文件/目录),并递归列出每个文件下的所有文件和目录以进行复制。
  3. GlobbedCopyListing:的另一种实现CopyListing在源路径扩大野生卡。
  4. FileBasedCopyListing:的实现CopyListing读取从指定文件的源路径列表。

根据是否在DistCpOptions中指定了源文件列表,将以下列方式之一生成源列表:

  1. 如果没有源文件列表,则使用GlobbedCopyListing。所有通配符都会被扩展,所有扩展都转发到SimpleCopyListing,后者进而构造列表(通过每个路径的递归下降)。
  2. 如果指定了源文件列表,则使用FileBasedCopyListing。从指定文件中读取源路径,然后将其转发到GlobbedCopyListing。然后按上述方式构建清单。

可以通过提供CopyListing接口的自定义实现来定制构建复制列表的方法。DistCp的行为在此与传统DistCp的不同之处在于如何考虑复制路径。

旧版实现仅列出必须明确复制到目标的那些路径。例如,如果目标处已存在文件(并且未指定-overwrite),则在MapReduce复制作业中甚至不考虑该文件。在安装过程中(即在MapReduce作业之前)进行确定涉及到文件大小和校验和比较,这可能会很费时。

新的DistCp将此类检查推迟到MapReduce作业,从而减少设置时间。由于这些检查在多个地图上并行进行,因此性能得到了进一步增强。

InputFormats和MapReduce组件

InputFormats和MapReduce组件负责从源到目标路径的文件和目录的实际副本。执行复制时,此时将使用在复制列表生成期间创建的列表文件。这里感兴趣的类别包括:

  • UniformSizeInputFormat: org.apache.hadoop.mapreduce.InputFormat的此实现提供与Legacy DistCp等效的功能,以平衡跨地图的负载。UniformSizeInputFormat的目的是使每个映射副本的字节数大致相同。适当地,清单文件被分成路径组,以使每个InputSplit中的文件大小总和几乎等于其他所有映射。拆分并不总是完美的,但是其琐碎的实现使安装时间很短。

  • DynamicInputFormat和DynamicRecordReader: DynamicInputFormat实现org.apache.hadoop.mapreduce.InputFormat,并且是DistCp的新增功能。列表文件被分为几个“块文件”,块文件的确切数量是Hadoop Job中请求的映射数量的倍数。在启动作业之前,每个映射任务都被“分配”了一个块文件之一(通过将块重命名为任务的ID)。使用DynamicRecordReader从每个块读取路径,并在CopyMapper中进行处理。处理完块中的所有路径后,将删除当前块并获取新的块。该过程一直持续到没有更多块可用为止。这种“动态”方法允许较快的映射任务比较慢的映射任务消耗更多的路径,从而总体上加快了DistCp作业。

  • CopyMapper:此类实现物理文件复制。根据输入选项(在作业的配置中指定)检查输入路径,以确定文件是否需要复制。仅当以下至少一项为真时,才会复制文件:

    • 目标文件中没有同名文件。
    • 目标处存在具有相同名称的文件,但文件大小不同。
    • 目标处存在具有相同名称的文件,但具有不同的校验和,并且未提及-skipcrccheck
    • 目标处存在同名文件,但指定了-overwrite
    • 目标处存在具有相同名称的文件,但是块大小不同(并且需要保留块大小。
  • CopyCommitter:此类负责DistCp作业的提交阶段,包括:

    • 保留目录权限(如果在选项中指定)
    • 清理临时文件,工作目录等

附录

地图尺寸

默认情况下,DistCp尝试比较每个映射的大小,以使每个副本大致复制相同数量的字节。请注意,文件是最好的粒度级别,因此增加同时复印机(即地图)的数量可能并不总是会增加同时复印的数量或整体吞吐量。

新的DistCp还提供了一种“动态”大小映射的策略,与较慢的节点相比,允许较快的数据节点复制更多字节。使用-strategy dynamic(在体系结构中说明),而不是将固定的源文件集分配给每个映射任务,而是将文件分为几组。集的数量超过地图的数量,通常是2-3倍。每个地图都会拾取并复制块中列出的所有文件。当一个块用完时,将获取并处理一个新的块,直到不再剩余任何块为止。

通过不将源路径分配给固定映射,与较慢的节点相比,较快的映射任务(即数据节点)能够消耗更多的块,从而复制更多的数据。尽管此分布不均匀,但对于每个映射器的容量而言,这是公平的。

动态策略由DynamicInputFormat实现。在大多数情况下,它都具有出色的性能。

对于长时间运行和定期运行的作业,建议将映射数调整为源群集和目标群集的大小,副本的大小以及可用带宽。

在HDFS版本之间复制

为了在Hadoop的两个不同主要版本之间(例如1.X和2.X之间)进行复制,通常将使用WebHdfsFileSystem。与以前的HftpFileSystem不同,由于webhdfs可用于读取和写入操作,因此DistCp可以在源群集和目标群集上运行。远程集群指定为webhdfs:// <namenode_hostname>:<http_port>。在Hadoop集群的相同主要版本之间(例如,在2.X和2.X之间)进行复制时,请使用hdfs协议以获得更好的性能。

使用distcp通过电线进行安全复制

使用SSL保护webhdfs时,请使用“ swebhdfs:// ”方案。有关更多信息,请参见SWebHDFS的SSL配置

MapReduce和其他副作用

如前所述,如果地图无法复制其输入之一,则会产生一些副作用。

  • 除非指定-overwrite,否则在重新执行时由先前映射成功复制的文件将被标记为“已跳过”。
  • 如果映射失败mapreduce.map.maxattempts次,则其余映射任务将被杀死(除非设置了-i)。
  • 如果将mapreduce.map.speculative设置为final和true,则副本的结果不确定。

DistCp和对象存储

DistCp可与对象存储(例如Amazon S3,Azure WASB和OpenStack Swift)一起使用。

先决条件

  1. 包含对象存储实现的JAR及其所有依赖项都位于类路径上。
  2. 除非JAR自动注册其捆绑的文件系统客户端,否则可能需要修改配置以声明实现文件系统架构的类。ASF自己的所有对象存储客户端都是自注册的。
  3. 相关的对象存储访问凭据必须在群集配置中可用,或者在所有群集主机中都可用。

DistCp可用于上传数据

hadoop distcp -direct hdfs:// nn1:8020 / datasets / set1 s3a:// bucket / datasets / set1

下载数据

hadoop distcp s3a://存储桶/生成的/结果hdfs:// nn1:8020 / results

在对象存储之间复制数据

hadoop distcp s3a:// bucket / generation / results \
  wasb://updates@example.blob.core.windows.net

并在对象存储中复制数据

hadoop distcp wasb://updates@example.blob.core.windows.net/current \
  wasb://updates@example.blob.core.windows.net/old

并使用-update仅复制更改的文件。

hadoop distcp -update -numListstatusThreads 20 \
  swift://history.cluster1/2016 \
  hdfs:// nn1:8020 / history / 2016

因为对象存储库列出文件的速度很慢,所以在大型目录树上执行-update操作(限制为40个线程)时,请考虑设置-numListstatusThreads选项。

DistCp -update与对象存储一起使用时,通常仅比较各个文件的修改时间和长度,而不比较任何校验和。大多数对象存储区确实具有目录的有效时间戳这一事实是无关紧要的。仅比较文件时间戳。但是,使客户端计算机的时钟接近基础架构的时钟很重要,这样客户端/ HDFS群集与对象存储的时间戳之间的时间戳是一致的。否则,更改的文件可能会经常丢失/复制。

笔记

  • -原子选项使临时数据的重命名,所以显著增加了在操作结束时提交的工作时间。此外,由于除(可选)wasb://以外的对象存储不提供目录的原子重命名,因此-atomic操作实际上无法提供所承诺的内容。避免

  • -append不支持的选项。

  • -diff使用rdiff不支持选项

  • 不管-skipCrc标志的值如何,都不会执行CRC检查。

  • 通常会忽略所有-p选项,包括保留权限,用户和组信息,属性校验和以及复制的选项。该wasb://连接器将保留这些信息,但不会强制执行的权限。

  • 一些对象存储连接器为输出的内存缓冲提供了一个选项,例如S3A连接器。在复制大文件时使用此选项可能会触发某种形式的内存不足事件,无论是堆溢出还是YARN容器终止。如果群集和对象存储之间的网络带宽受到限制(例如在使用远程对象存储时),则这特别常见。最好禁用/避免此类选项,并依靠磁盘缓冲。

  • 即使在对象存储库内部实现了更有效的COPY操作时,单个对象存储库中的复制操作仍会在Hadoop集群中进行

    也就是说,诸如

    hadoop distcp s3a:// bucket / datasets / set1 s3a:// bucket / datasets / set2

    将每个字节向下复制到Hadoop工作节点,然后复制回存储桶。除了速度慢之外,这还意味着可能会产生费用。

  • -direct选项可用于直接写入到对象存储器目标路径,避免了否则会发生的潜在的非常昂贵的临时文件重命名操作。

经常问的问题

  1. 为什么-update不能在预先存在的目标目录下创建父源目录?-update-overwrite的行为在本文档的“用法”部分中进行了详细说明。简而言之,如果将任一选项与预先存在的目标目录一起使用,则将复制每个源目录的内容,而不是源目录本身。此行为也与旧版DistCp实现一致。

  2. 新的DistCp在语义上与旧版DistCp有何不同?

    • 使用旧版DistCp复制时,在复制过程中跳过的文件过去也具有不变的文件属性(权限,所有者/组信息等)。现在,即使跳过了文件副本,这些文件也已更新。
    • 在旧版DistCp中,未在目标上创建源路径输入中的空根目录。现在已创建。
  3. 为什么新的DistCp使用的地图比旧的DistCp更多?旧版DistCp的工作原理是,在启动复制作业之前,先确定需要实际复制哪些文件到目标,然后启动复制所需的任意数量的地图。因此,如果需要跳过大多数文件(例如,因为它们已经存在),则需要的映射将更少。结果,设置所花费的时间(即在M / R作业之前)要更长。新的DistCp仅计算源路径的内容。它不会尝试筛选出可以跳过哪些文件。该决定将推迟到M / R作业运行之前。这要快得多(相对于执行时间),但是启动的映射数将在-m选项中指定,如果未指定,则为20(默认)。

  4. 指定更多地图时,为什么DistCp不能运行得更快?当前,DistCp的最小工作单元是一个文件。即,一个文件仅由一个地图处理。将映射数增加到超过文件数的值将不会产生性能优势。启动的地图数量将等于文件数量。

  5. 为什么DistCp的内存不足?如果从源路径复制的单个文件/目录的数量非常大(例如1,000,000个路径),则DistCp可能会在确定复制路径列表时用尽内存。这对于新的DistCp实现不是唯一的。要解决此问题,请考虑更改-Xmx JVM堆大小参数,如下所示:

     bash $ export HADOOP_CLIENT_OPTS =“-Xms64m -Xmx1024m”
     bash $ hadoop distcp / source / target