Hadoop MapReduce提供嵌套目录作为作业输入

sa1*_*125 22 hadoop nested mapreduce directory-walk

我正在处理一个处理嵌套目录结构的工作,包含多个级别的文件:

one/
??? three/
?   ??? four/
?       ??? baz.txt
?       ??? bleh.txt
?       ??? foo.txt
??? two/
    ??? bar.txt
    ??? gaa.txt
Run Code Online (Sandbox Code Playgroud)

当我添加one/为输入路径时,不会处理任何文件,因为根级别不会立即提供任何文件.

我读到了job.addInputPathRecursively(..),但这似乎已在最近的版本中被弃用(我使用的是hadoop 1.0.2).我已经编写了一些代码来遍历文件夹并添加每个目录job.addInputPath(dir),直到作业崩溃时,由于某种原因尝试处理目录作为输入文件,例如 - 尝试fs.open(split.getPath()),何时split.getPath()是目录(这发生在内部LineRecordReader.java) .

我试图说服自己必须有一种更简单的方法来提供一个嵌套目录结构的工作.有任何想法吗?

编辑 - 显然这是一个开放的错误.

Che*_*eng 14

我没有找到任何关于此的文件但是*/*有效.所以它是-input 'path/*/*'.


小智 7

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

FileInputFormat.setInputDirRecursive(job,true);

不,谢谢,叫我雷锋吧!


Don*_*ner 4

我发现递归地遍历数据可能很危险,因为可能存在来自distcp或类似的东西的挥之不去的日志文件。让我提出一个替代方案:

在命令行上执行递归遍历,然后将空格分隔参数中的路径传递到 MapReduce 程序中。从以下位置获取列表argv

$ hadoop jar blah.jar "`hadoop fs -lsr recursivepath | awk '{print $8}' | grep '/data.*\.txt' | tr '\n' ' '`"
Run Code Online (Sandbox Code Playgroud)

很抱歉花了这么长时间,但它完成了工作。您可以将其包装在 bash 脚本中,将其分解为变量。

我个人喜欢使用传入文件路径的方法来编写我的mapreduce作业,这样代码本身就没有硬编码的路径,并且我可以相对容易地将其设置为针对更复杂的文件列表运行。