我正在处理一个处理嵌套目录结构的作业,该结构包含多个级别的文件:
one/
├── three/
│ └── four/
│ ├── baz.txt
│ ├── bleh.txt
│ └── foo.txt
└── two/
├── bar.txt
└── gaa.txt
当我添加one/
作为输入路径时,不会处理任何文件,因为根级别不会立即提供任何文件。
我读到了job.addInputPathRecursively(..)
,但这似乎在最近的版本中被弃用了(我使用的是hadoop 1.0.2)。我已经编写了一些代码来遍历文件夹并添加每个目录job.addInputPath(dir)
,直到作业由于某种原因尝试处理目录作为输入文件时崩溃,例如 - 当fs.open(split.getPath())
是目录时尝试split.getPath()
(这发生在LineRecordReader.java
内)。
我试图说服自己必须有一种更简单的方法来提供嵌套目录结构的作业。有什么想法吗?
编辑 - 显然此处有open bug。
答案 0 :(得分:14)
我没有找到任何关于此的文件,但*/*
有效。所以它是-input 'path/*/*'
。
答案 1 :(得分:6)
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
FileInputFormat.setInputDirRecursive(job,true);
不,谢谢,请叫我雷锋!
答案 2 :(得分:4)
我发现递归遍历数据可能很危险,因为distcp
或类似的东西可能存在延迟的日志文件。让我提出一个替代方案:
在命令行上执行递归遍历,然后将空格分隔参数中的路径传递到MapReduce程序中。从argv
:
$ hadoop jar blah.jar "`hadoop fs -lsr recursivepath | awk '{print $8}' | grep '/data.*\.txt' | tr '\n' ' '`"
很抱歉这个漫长的打击,但它完成了工作。你可以将这个东西包装在一个bash脚本中,以便将事情分解为变量。
我个人喜欢使用pass-in-filepath方法来编写mapreduce作业,因此代码本身没有硬编码路径,而且我可以相对轻松地将其设置为针对更复杂的文件列表运行。
答案 3 :(得分:1)
不知道是否仍然相关但至少在hadoop 2.4.0中你可以将属性 mapreduce.input.fileinputformat.input.dir.recursive 设置为 true 它会解决你的问题。
答案 4 :(得分:-1)
只需使用FileInputFormat.addInputPath(“with file pattern”); 我正在编写我的第一个hadoop prog用于图形分析,其中输入来自.dz格式的diff目录... 它对我有用!!!