DistCp
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)的令牌续订出现问题,相应调整该值。
评论
登录后参与评论
KnowForge