在我的工作中,我需要解析许多历史日志集。个别客户(有数千个)可能有数百个按日期分类的日志子目录。例如:
每个单独的日志集本身可能有五到六个级别,包含数千个文件。
因此,我实际上希望各个映射作业处理子目录的步骤:简单地枚举单个文件是我的分布式计算问题的一部分!
不幸的是,当我尝试将只包含日志子目录的目录传递给Hadoop时,它抱怨我无法将这些子目录传递给我的映射器。 (同样,我已经写过接受子目录作为输入):
$ hadoop jar "${HADOOP_HOME}/contrib/streaming/hadoop-streaming-${HADOOP_VERSION}.jar" -input file:///mnt/logs/Customer_Name/ -file mapper.sh -mapper "mapper.sh" -file reducer.sh -reducer "reducer.sh" -output .
[ . . . ]
12/04/10 12:48:35 ERROR security.UserGroupInformation: PriviledgedActionException as:cloudera (auth:SIMPLE) cause:java.io.IOException: Not a file: file:/mnt/logs/Customer_Name/2011-05-20-003
12/04/10 12:48:35 ERROR streaming.StreamJob: Error Launching job : Not a file: file:/mnt/logs/Customer_Name/2011-05-20-003
Streaming Command Failed!
[cloudera@localhost ~]$
有没有一种简单的方法来说服Hadoop-streaming允许我将目录分配为工作项?
答案 0 :(得分:1)
我想您需要调查编写一个自定义的InputFormat,您也可以传递根目录,它将为每个客户创建一个拆分,然后每个拆分的记录读取器将执行目录遍历并将文件内容推送到你的地图制作者
答案 1 :(得分:0)
Hadoop支持输入路径为正则表达式。我没有尝试过很多复杂的正则表达式,但简单的占位符?和 * 确实有效。
因此,在您的情况下,我认为如果您将以下内容作为输入路径,它将起作用:
file:///mnt/logs/Customer_Name/*/*
可能不需要最后一个星号,因为最终目录中的所有文件都会自动添加为输入路径。