我正在尝试使用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,但我需要一种有效且安全的方法来删除实际复制的文件。
答案 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。
除其他外,如果目录存在,它的重命名将(可选)失败。 这不会产生请求的合并,但至少会引发异常并且不会创建不需要的子目录。