集成

DistCp

师成师成· 更新于 2026-09-28· 阅读 11 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Hadoop DistCp 是一个基于命令行、基于 MapReduce 的批量数据复制工具。

hadoop distcp 命令可用于在 Ozone 与任意 Hadoop 兼容文件系统(如 HDFS 或 S3A)之间相互复制数据。

基本用法

要将文件从源 Ozone 集群目录复制到目标 Ozone 集群目录,请使用以下命令:

hadoop distcp ofs://ozone1/vol1/bucket/dir1 ofs://ozone2/vol2/bucket2/dir2

必须在 ozone-site.xml 配置文件中分别为 ozone1 和 ozone2 集群定义服务 ID。例如:

<property>
  <name>ozone.om.service.ids</name>
  <value>ozone1,ozone2</value>
</property>

接下来,定义它们的逻辑映射。有关更多详细信息,请参阅 OM 高可用性文档。

从 HDFS 复制到 Ozone

DistCp 会执行文件校验和检查,以确保文件完整性。但是,由于 HDFS 的默认校验和类型(CRC32C)与 Ozone 的默认校验和类型(CRC32)不同,文件校验和检查将导致 DistCp 作业失败。

为防止作业失败,请在 DistCp 命令中指定校验和选项,强制 Ozone 使用与 HDFS 相同的校验和类型。

示例:

hadoop distcp \
  -Ddfs.checksum.combine.mode=COMPOSITE_CRC \
  -Dozone.client.checksum.type=CRC32C \
  hdfs://ns1/tmp ofs://ozone1/vol1/bucket1/dst

注意: 如果 HDFS 集群运行的是 Hadoop 3.1.1 或更高版本,则不需要参数 -Ddfs.checksum.combine.mode=COMPOSITE_CRC。

或者,你可以完全跳过文件校验和检查:

hadoop distcp \
  -skipcrccheck \
  hdfs://ns1/tmp ofs://ozone1/vol1/bucket1/dst

从 Ozone 复制到 HDFS

在将文件从 Ozone 复制到 HDFS 时,由于校验和类型的不同,也可能出现类似的问题。在这种情况下,由于 HDFS 是目标系统,必须为 HDFS 配置校验和类型。

示例:

hadoop distcp \
  -Ddfs.checksum.combine.mode=COMPOSITE_CRC \
  -Ddfs.checksum.type=CRC32 \
  ofs://ozone1/vol1/bucket1/src hdfs://ns1/tmp/dst

通过指定适当的校验和配置或跳过验证,你可以确保 DistCp 作业在 HDFS 与 Ozone 之间传输数据时成功完成。

加密数据

当数据位于 HDFS 加密区或 Ozone 加密桶中时,文件校验和将不匹配。这是因为在目标端使用了新的 EDEK(Encryption Data Encryption Key,加密数据加密键),导致底层块数据不同。在这种情况下,请指定 -skipcrccheck 参数以避免作业失败。

注意: 从 Ozone 2.0 开始,支持加密 Ozone 集群之间的 DistCp。

有关使用 Hadoop DistCp 的更多信息,请参阅 Hadoop DistCp 指南。

常见问题排查

委托令牌问题

如果 DistCp 命令失败,且错误输出中包含 "OzoneToken",说明在从目标(或源)Ozone 集群获取委托令牌时出现问题。此时请确保在客户端配置中显式启用了 Ozone 的安全性。

在运行 DistCp 命令的节点上,向 ozone-site.xml 中添加以下属性:

<property>
  <name>ozone.security.enabled</name>
  <value>true</value>
</property>

这有助于客户端与 Ozone 正确地进行安全通信协议交互。

跨域 Kerberos(Ozone 1.x)

受影响版本: Ozone 1.x

当针对一个与客户端或源/目标集群处于不同 Kerberos 域的 Ozone 集群执行 DistCp 命令(或其他 HDFS 兼容命令,如 hdfs dfs -ls)时,Ozone 1.x 版本可能会产生类似如下的错误:

24/02/07 18:47:36 INFO retry.RetryInvocationHandler: com.google.protobuf.ServiceException: java.io.IOException: DestHost:destPort host1.dst.example.com:9862, LocalHost:localPort host1.src.example.com/10.140.99.144:0. Failed on local exception: java.io.IOException: Couldn't set up I/O streams: java.lang.IllegalArgumentException: Server has invalid Kerberos principal: om/host1.dst.example.com@DST.LOCAL, expecting: OM/host1.dst.example.com@REALM, while invoking $Proxy10.submitRequest over nodeId=om26,nodeAddress=host1.dst.example.com:9862 after 3 failover attempts. Trying to failover immediately.

原因: 通常情况下,这是因为 Ozone Manager 的 Kerberos 主体(ozone.om.kerberos.principal)未定义,或其定义方式不适用于跨 realm 交互。客户端期望获得来自其自身 realm 或某个特定受信任 realm 的主体,因此出现不匹配。此问题已在 Ozone 2.0 中得到解决。

解决方法(针对 Ozone 1.x): 若要在 Ozone 1.x 中解决此问题,请在运行 DistCp 的客户端机器的 ozone-site.xml 中添加以下属性(如果 Ozone Manager 也需要跨 realm 互相通信,则可能还需要在各 Ozone Manager 上添加该属性):

<property>
  <name>ozone.om.kerberos.principal.pattern</name>
  <value>*</value>
</property>

该配置放宽了主体(principal)匹配规则,允许客户端接受来自不同 realm 的 Ozone Manager 主体。

修复: 该缺陷由 HDDS-10328 追踪,并已在 Ozone 2.0 及更高版本中修复。升级到 Ozone 2.0+ 是推荐的长期解决方案。

双向跨 realm 信任环境中的令牌续期失败

在具有双向跨 realm Kerberos 信任的环境中,DistCp 作业(作为 MapReduce 作业运行)可能会因委托令牌续期出错而在执行期间失败。错误示例如下:

24/02/08 00:35:00 ERROR tools.DistCp: Exception encountered
java.io.IOException: org.apache.hadoop.yarn.exceptions.YarnException: Failed to submit application_1707350431298_0001 to YARN: Failed to renew token: Kind: HDFS_DELEGATION_TOKEN, Service: 10.140.99.144:8020, Ident: (token for systest: HDFS_DELEGATION_TOKEN owner=user1@SRC.EXAMPLE.COM, renewer=yarn, realUser=, issueDate=1707352474394, maxDate=1707957274394, sequenceNumber=44, masterKeyId=14)

当 MapReduce 作业尝试为远程 HDFS 或 Ozone 文件系统续期委托令牌,而续期因跨 realm(Kerberos 领域)的复杂性而失败时,就会出现这种情况。错误中的 Service 字段(例如 10.140.99.144:8020)通常表示令牌续期失败的文件系统。

解决方案: 你可以通过 -Dmapreduce.job.hdfs-servers.token-renewal.exclude 参数,阻止 DistCp MapReduce 作业尝试为特定的 HDFS 兼容文件系统续期委托令牌。该参数的值应填写令牌续期出现问题的集群的 authority(主机名或服务 ID)。

参数:

-Dmapreduce.job.hdfs-servers.token-renewal.exclude=<authority_of_filesystem_to_exclude>

对于 HDFS 集群,<authority_of_filesystem_to_exclude> 是其 NameNode 地址(例如 namenode.example.com:8020,如果端口为标准端口,也可以只写 namenode.example.com)。对于 Ozone 集群,它是其服务 ID(例如 ozoneprod)。

示例: 假设你在一个与目标 Ozone 集群(ofs://ozone1707264383/...)关联的 YARN 集群上运行 DistCp 命令,从源 HDFS 集群(hdfs://host1.src.example.com:8020/...)复制数据,而源 HDFS 集群的令牌续期失败:

hadoop distcp \
  -Dmapreduce.job.hdfs-servers.token-renewal.exclude=host1.src.example.com \
  -Ddfs.checksum.combine.mode=COMPOSITE_CRC \
  -Dozone.client.checksum.type=CRC32C \
  hdfs://host1.src.example.com:8020/tmp/ \
  ofs://ozone1707264383/tmp/dest

在此示例中,host1.src.example.com 是源 HDFS 集群的 authority,其令牌不会由 DistCp MapReduce 作业续订。请根据哪个集群(源或目标、HDFS 或 Ozone)的令牌续订出现问题,相应调整该值。

评论

登录后参与评论

正在加载评论…