当目录存在时,hdfs moveFromLocal中的奇怪行为

时间:2014-02-02 10:40:20

标签: hadoop hdfs

我正在尝试使用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),这是有问题的

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

2 个答案:

答案 0 :(得分:1)

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

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

不幸的是你必须先清理dst dir:“hadoop fs -rmr dst”。

答案 1 :(得分:0)

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

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