7

在我的工作中,我需要解析许多历史日志集。个别客户(有数千个)可能有数百个按日期划分的日志子目录。例如:

  • 日志/Customer_One/2011-01-02-001
  • 日志/Customer_One/2012-02-03-001
  • 日志/Customer_One/2012-02-03-002
  • 日志/Customer_Two/2009-03-03-001
  • 日志/Customer_Two/2009-03-03-002

每个单独的日志集本身可能有五到六级深度并包含数千个文件。

因此,我实际上希望单个地图作业能够处理遍历子目录:简单地枚举单个文件是我的分布式计算问题的一部分!

不幸的是,当我尝试将仅包含日志子目录的目录传递给 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 允许我将目录分配为工作项?

4

2 回答 2

2

Hadoop 支持输入路径为正则表达式。我没有尝试过很多复杂的正则表达式,但是简单的占位符*确实有效。

因此,在您的情况下,我认为如果您将以下内容作为输入路径,它将起作用:

file:///mnt/logs/Customer_Name/*/*

最后一个星号可能不需要,因为最终目录中的所有文件都会自动添加为输入路径。

于 2013-03-31T17:54:43.767 回答
2

我想您需要研究编写一个自定义 InputFormat ,您也可以传递根目录,它将为每个客户创建一个拆分,然后每个拆分的记录读取器将执行目录遍历并将文件内容推送到您的映射器

于 2012-04-10T21:04:00.603 回答