使用Python Mapper进行Hadoop流式传输的多个输出文件

时间:2013-08-30 21:09:48

标签: python hadoop

我正在寻找关于这个问题的答案的一点澄清:

Generating Separate Output files in Hadoop Streaming

我的用例如下:

我有一个map-only 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)摆脱初始列的最佳方法是什么?

1 个答案:

答案 0 :(得分: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

  6. 执行这些操作后,您应该会在 outputpath 中看到两个目录,其中 valid_file_name ,另一个目录 err_file_name 。所有将valid_file_name作为标记的记录将转到valid_file_name目录,所有具有err_file_name的记录将转到err_file_name目录。

    我希望所有这些都有道理。