2015-12-29 71 views
4

我想知道如何在HDFS mv命令?如何HDFS mv命令工作

  1. 它只是一个符号变化,没有任何实际的数据移动?

    • 如果的moveTo目录存在(可以是差异分区)
    • 如果moveTo将新目录
  2. 是否有可能损坏数据,而Hadoop的中移动大文件?那么cpdistcp是一个更安全的选择?

回答

5

当用户调用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 StorageOpenStack Swift的替代文件系统插件。还有很多供应商已经创建了自己的文件系统插件。这些替代文件系统是否提供原子重命名语义是这些其他文件系统的实现细节。 S3和Swift插件实现重命名为复制 - 然后删除,所以它们绝对不提供原子性保证。 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也可以执行源和目标之间的校验和比较作为后处理步骤。

1

mv(移动)只是一个元数据操作。没有数据移动,如cp(复制)。

你可以很容易地测试它。我会用例子来解释。

  1. 我有一个文件/tmp/1.txt

    我运行下面的命令:

    hdfs fsck /tmp/1.txt -files -blocks -locations 
    

    我获得以下的输出:

    /tmp/1.txt 5 bytes, 1 block(s): OK 
    0. BP-1788638071-172.23.206.41-1439815305280:blk_1073747956_7133 len=5 repl=1 [DatanodeInfoWithStorage[192.168.56.1:50010,DS-cf19d920-d98b-4877-9ca7-c919df1a869a,DISK]] 
    
  2. 我谨(mv)文件/tmp/1.txt/tmp/1_renamed.txt,这是同一个目录下/tmp

    我运行下面的命令:

    hdfs fsck /tmp/1_renamed.txt -files -blocks -locations 
    

    我获得以下的输出:

    /tmp/1_renamed.txt 5 bytes, 1 block(s): OK 
    0. BP-1788638071-172.23.206.41-1439815305280:blk_1073747956_7133 len=5 repl=1 [DatanodeInfoWithStorage[192.168.56.1:50010,DS-cf19d920-d98b-4877-9ca7-c919df1a869a,DISK]] 
    
  3. 我谨(mv)文件/tmp/1_renamed.txt/tmp1/1.txt,这是一个不同的目录下/tmp1

    我运行下面的命令:

    hdfs fsck /tmp1/1.txt -files -blocks -locations 
    

    我获得以下的输出:

    /tmp1/1.txt 5 bytes, 1 block(s): OK 
    0. BP-1788638071-172.23.206.41-1439815305280:blk_1073747956_7133 len=5 repl=1 [DatanodeInfoWithStorage[192.168.56.1:50010,DS-cf19d920-d98b-4877-9ca7-c919df1a869a,DISK]] 
    

你可以看到,该块报告中的所有3次mv操作之后是相同的:

0. BP-1788638071-172.23.206.41-1439815305280:blk_1073747956_7133 len=5 repl=1 [DatanodeInfoWithStorage[192.168.56.1:50010,DS-cf19d920-d98b-4877-9ca7-c919df1a869a,DISK]] 

它确认,mv只是在名称节点中重命名文件名。在“Chris Nauroth”给出的另一个答案中,他已经清楚地解释了如何执行mv操作。

数据损坏: 这是可能的,而使用cpdistcp复制数据可能会遭到损坏。但是,在这两种情况下,你都可以检查腐败情况。

  1. cp命令

    hadoop fs -checksum可用于检查文件的校验和。

    我将文件/tmp/1GB/part-m-00000复制到另一个目录/tmp1/part-m-00000。然后执行以下命令:

    hadoop fs -checksum /tmp/1GB/part-m-00000 /tmp1/part-m-00000 
    
    /tmp/1GB/part-m-00000 MD5-of-262144MD5-of-512CRC32 0000020000000000000400008f15c32887229c0495a23547e2f0a29a 
    /tmp1/part-m-00000  MD5-of-262144MD5-of-512CRC32 0000020000000000000400008f15c32887229c0495a23547e2f0a29a 
    

    您可以看到原始文件和复制文件的校验和匹配。因此,在复制文件后,您可以执行hadoop fs -checksum命令来检查2个文件的校验和是否匹配。

  2. distcp命令

    默认情况下,distcp比较的源文件和目标文件的校验和,复制操作完成后。如果校验和不匹配,则distcp将复制操作标记为FAILED。您可以通过调用distcp-skipcrccheck选项来禁用校验和比较。