HDFS EC 对 distcp 的影响

distcp 在拷贝一个文件结束后,会对比源文件和目标文件的校验值,判断两者是否一致。其中文件的校验值通过 FileSystem.getFileChecksum(Path) API 获取,该 API 本质上是一个针对 DataNode 的 RPC 调用,需要 DataNode 高度配合才能完成。

Hadoop 3.x 引入 EC 后,由于 EC 文件和副本文件的布局(layout)不同,所以,即使是同一个文件,在分别使用副本模式和 EC 模式保存时,也会得到两个不同的校验值,导致对比失败,进而 distcp 出错。

要解决这个问题,有两个方案:

方案一

跳过源文件和目标文件的校验值对比,添加如下参数:-skipcrccheck,这个方案非常简单。

方案二

client 在获取文件的校验值时,指定使用 CRC 模式进行获取(默认使用 MD5 模式),这两个模式的区别是:

  1. MD5 模式本质上并不是针对文件内容的校验,而是针对 meta 文件内容的校验,而同一个文件在副本和 EC 两种情况下,会生成不同个数、不同大小的 meta 文件,这时候得到的校验值是不同的。
  2. CRC 模式本质上是针对文件内容的校验,同一个文件,无论是以副本形式保存,还是以 EC 形式保存,只要文件的内容相同,那么校验值就是一致的。

CRC 模式是 HDFS 的一个新特性,相关的 patch 主要是 HDFS-13056. Expose file-level composite CRCs in HDFS which are comparable across different instances/layouts,这个 patch 规模较大.

需要特别强调两点:

  1. 对同样一个文件,MD5 和 CRC 这两种模式得到的校验值是不同的。
  2. 无论哪种校验模式,都需要客户端和 DN 一起配合使用,特别的,对于本次新引入的 CRC 模式,如果 DN 不支持,那么最终将导致客户端异常退出。

如果需要在 2.8.5 和 3.2.1 集群之间进行副本文件和 EC 文件的 distcp,那么需要启用 CRC 模式,那么需要:

  1. 升级所有计算集群节点的 hadoop 客户端版本,并添加如下客户端配置,指定使用 CRC 校验模式:

    dfs.checksum.combine.mode
    COMPOSITE_CRC

  1. 升级 2.8.5 HDFS 集群的所有 DataNode 到最新版本,目的:确保 2.5 的 DN 支持 CRC 校验模式。

关于 skipcrcheck 的建议

HDFS 本身在读、写文件的过程中有完整的校验策略,能够保证:

  • distcp 从源文件读取到内存中的数据一定是准确的。
  • distcp 从内存写入到目标文件中的数据一定是准确的。
  • distcp 默认会对比源文件和目标文件的长度是否一致。

distcp 本质上就是一读一写,现在我们已经分别保证了读、写的准确性,那么简单推理可知,只要 distcp 本身没有 bug,那么最终源文件和目标文件肯定是一致的。在这种情况下,使用 -skipcrccheck 影响不大。

你可能感兴趣的:(HDFS EC 对 distcp 的影响)