【问题标题】:Strange behaviour in hdfs moveFromLocal when directories exists目录存在时 hdfs moveFromLocal 中的奇怪行为
【发布时间】:2018-06-19 02:51:42
【问题描述】:

我正在尝试使用 moveFromLocal hdfs shell 命令将文件(树结构)从本地文件系统移动到 hdfs。

如果目标子目录不存在,一切正常。 但如果它们存在(这是一般情况 - 将文件添加到现有目录中),则会创建层次结构中的另一个级别

示例:

磁盘上的原始结构

$ find src
src
src/a
src/a/2
src/a/2/file1
src/a/1
src/a/1/file1
src/a/4
src/a/4/file1
src/a/3
src/a/3/file1
src/b
src/b/2
src/b/2/file1
src/b/1
src/b/1/file1
src/b/4
src/b/4/file1
src/b/3
src/b/3/file1

移动命令

$hdfs dfs -moveFromLocal src/* /dst

结果(如预期)

$ hdfs dfs -ls  -R /dst
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/1/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/2/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/3/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/4/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/1/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/2/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/3/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/4/file1

第二批本地文件

$ find src
src
src/a
src/a/2
src/a/2/file2
src/a/1
src/a/1/file2
src/a/4
src/a/4/file2
src/a/3
src/a/3/file2
src/b
src/b/2
src/b/2/file2
src/b/1
src/b/1/file2
src/b/4
src/b/4/file1
src/b/3
src/b/3/file2

将第二批移动到 hdfs

$ hdfs dfs -moveFromLocal src/* /dst

第二批关于hdfs的

注意所有的“file2”都在一个双层次结构中(a/a,而不仅仅是a)

$ hdfs dfs -ls  -R /dst
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/1/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/2/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/3/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/a/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/a/4/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a/a
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a/a/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/a/a/1/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a/a/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/a/a/2/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a/a/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/a/a/3/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/a/a/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/a/a/4/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/1/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/2/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/3/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:39 /dst/b/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:39 /dst/b/4/file1
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b/b
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b/b/1
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/b/b/1/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b/b/2
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/b/b/2/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b/b/3
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/b/b/3/file2
drwxr-xr-x   - root supergroup          0 2014-02-02 03:42 /dst/b/b/4
-rw-r--r--   3 root supergroup          0 2014-02-02 03:42 /dst/b/b/4/file1

编辑

我知道这种行为是设计使然... 我愿意接受性能相同的替代解决方案。

  • 最简单的解决方案是创建一个单独移动每个文件的循环,由于性能问题,这是有问题的(每个 hdfs 命令都会启动一个新的 jvm)

  • 我也考虑过使用复制而不是移动,但我需要一种有效且安全的方法来删除实际复制的文件。

【问题讨论】:

    标签: hadoop hdfs


    【解决方案1】:

    这种行为与 Unix 上的 mv 一致(有点)——尽管它的手册页没有记录它,但如果目标目录包含文件,mv 将拒绝将目录重命名为另一个目录:

    [evgeny@dev1]\$ mv src/* dst/
    mv: 无法将 'src/subsrc' 移动到 'dst/subsrc': 目录不为空

    不幸的是,您必须先清理 dst 目录:“hadoop fs -rmr dst”。

    【讨论】:

    • linux mv 失败,但根本不移动文件。无论如何,删除现有文件不是解决方案,因为它们仍然需要
    • 这并不理想,但是,鉴于我们得到的,您的解决方案可能应该是:copyToLocal、merge (rsync -r src/* dst/)、-expunge dst、moveFromLocal
    【解决方案2】:

    org.apache.hadoop.fs.FileContext(包装器\替换 org.apache.hadoop.fs.FileSystem) 有更简洁的 API。

    除其他外,如果目录存在,重命名将(可选)失败。 这不会进行请求的合并,但至少会引发异常并且不会创建不需要的子目录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      相关资源
      最近更新 更多