当用户调用hdfs dfs -mv时,HDFS保证重命名操作的原子性.运行此命令时,客户端对NameNode进行RPC调用.此RPC的NameNode实现在修改inode树时保持锁定,并且只有在重命名完成后才会成功锁定或成功锁定. (由于许可或配额违规等原因,它可能会失败.)

由于实现完全在NameNode内执行并且仅操纵文件系统元数据,因此不涉及实际的数据移动.实际上,在hdfs dfs -mv命令期间,没有与DataNode的交互.所有文件的块保持不变,与inode关联的阻止列表保持不变. NameNode只是从一个位置获取该文件的inode,并将其移动到文件系统树中的另一个位置.不会破坏块数据.

由于NameNode提供了重命名的保证原子实现,因此也不存在元数据损坏的可能性.不可能最终处于“半完成”状态,文件存在于两个地方,甚至更糟,完全被删除.

现在我需要在上面的答案中添加一个微妙的变化.大多数情况下,在运行HDFS shell命令时,通常与HDFS作为后备文件系统进行交互.但是,这不是唯一可能的文件系统实现. Apache Hadoop发行版附带了S3,Azure Storage和OpenStack Swift的替代文件系统插件.还有许多供应商已经创建了自己的文件系统插件.这些备用文件系统是否提供原子重命名语义是这些其他文件系统的实现细节. S3和Swift插件实现重命名为copy-then-delete,因此它们绝对不提供原子性保证. Azure存储插件通过使用Azure存储blob租约确实为原子重命名提供了一些可选支持,但它不是默认行为.

此外,由于这个原因,不可能跨越不同的文件系统运行hdfs dfs -mv.您必须使用复制命令,然后它将涉及完整的数据副本.当您尝试跨文件系统重命名时会发生以下情况.该示例尝试在HDFS安装中为源文件和本地文件系统上的目标运行hdfs dfs -mv.该命令被拒绝.

> hdfs dfs -mv hdfs:///testData file:///tmp/testData

mv: `hdfs:///testData': Does not match target filesystem

问题的最后一部分询问复制时是否可能损坏数据. Hadoop将在读取文件时执行校验和验证,因此预计客户端不会看到损坏的数据. DistCp还可以执行源和目标之间的校验和比较作为后处理步骤.