7

我在这里寻找对这个问题的答案的一点澄清:

在 Hadoop Streaming 中生成单独的输出文件

我的用例如下:

我有一个仅映射的 mapreduce 作业,它需要一个输入文件,进行大量的解析和处理,然后写回。但是,某些行的格式可能不正确,如果是这种情况,我想将原始行写入单独的文件。

似乎这样做的一种方法是将文件名添加到我正在打印的行中并使用 multipleOutputFormat 参数。例如,如果我最初有:

if line_is_valid(line):
    print name + '\t' + comments

我可以改为:

if line_is_valid(line):
    print valid_file_name + '\t' + name + '\t' + comments
else:
    print err_file_name + '\t' + line

我对这个解决方案的唯一问题是我不希望 file_name 出现在文本文件中的第一列。我想我可以运行另一个作业来删除每个文件的第一列,但这似乎有点愚蠢。所以:

1) 这是使用 python mapreduce 作业管理多个输出文件的正确方法吗?

2)摆脱该初始列的最佳方法是什么?

4

1 回答 1

18

您可以执行以下操作,但它涉及一些 Java 编译,如果您希望使用 Python 完成您的用例,我认为这不应该是一个问题 - 据我所知,从 Python 中直接不可能根据您的用例在单个作业中的要求,从最终输出中跳过文件名。但是下面显示的内容可以轻松实现!

这是需要编译的 Java 类 -

package com.custom;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat;

 public class CustomMultiOutputFormat extends MultipleTextOutputFormat<Text, Text> {
        /**
        * Use they key as part of the path for the final output file.
        */
       @Override
       protected String generateFileNameForKeyValue(Text key, Text value, String leaf) {
             return new Path(key.toString(), leaf).toString();
       }

       /**
        * We discard the key as per your requirement
        */
       @Override
       protected Text generateActualKey(Text key, Text value) {
             return null;
       }
 }

编译步骤:

  1. 将文本完全保存到文件(没有不同的名称) CustomMultiOutputFormat.java
  2. 当您在上述保存文件所在的目录中时,键入 -

    $JAVA_HOME/bin/javac -cp $(hadoop classpath) -d . CustomMultiOutputFormat.java

  3. 在尝试上述命令之前,请确保将 JAVA_HOME 设置为 /path/to/your/SUNJDK。

  4. 使用(准确输入)制作您的 custom.jar 文件 -

    $JAVA_HOME/bin/jar cvf custom.jar com/custom/CustomMultiOutputFormat.class

  5. 最后,像这样运行你的工作 -

    hadoop jar /path/to/your/hadoop-streaming-*.jar -libjars custom.jar -outputformat com.custom.CustomMultiOutputFormat -file your_script.py -input inputpath --numReduceTasks 0 -output outputpath -mapper your_script.py

完成这些之后,您应该会在输出路径中看到两个目录,一个带有valid_file_name,另一个带有err_file_name。所有以 valid_file_name 作为标签的记录都将进入 valid_file_name 目录,所有具有 err_file_name 的记录将进入 err_file_name 目录。

我希望所有这些都有意义。

于 2013-09-01T19:58:39.520 回答