Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python Mapper的Hadoop流的多个输出文件_Python_Hadoop - Fatal编程技术网

使用Python Mapper的Hadoop流的多个输出文件

使用Python Mapper的Hadoop流的多个输出文件,python,hadoop,Python,Hadoop,我想在这里澄清一下这个问题的答案: 我的用例如下所示: 我有一个map-only mapreduce作业,它接受一个输入文件,进行大量解析和搜索,然后写回。但是,某些行的格式可能不正确,如果是这样,我想将原始行写入一个单独的文件 这样做的一种方法似乎是将文件名前置到我正在打印的行,并使用multipleOutputFormat参数。例如,如果我最初有: if line_is_valid(line): print name + '\t' + comments 我可以这样做: if li

我想在这里澄清一下这个问题的答案:

我的用例如下所示:

我有一个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
这个解决方案的唯一问题是,我不希望文件名显示为textfiles中的第一列。我想我可以运行另一个作业来删除每个文件的第一列,但这似乎有点愚蠢。因此:

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


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

您可以执行以下操作,但它涉及到一点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;
       }
 }
package.com.custom;
导入org.apache.hadoop.fs.Path;
导入org.apache.hadoop.io.Text;
导入org.apache.hadoop.mapred.lib.MultipleTextOutputFormat;
公共类CustomMultiOutputFormat扩展了MultipleTextOutputFormat{
/**
*使用它们键作为最终输出文件路径的一部分。
*/
@凌驾
受保护的字符串generateFileNameForKeyValue(文本键、文本值、字符串叶){
返回新路径(key.toString(),leaf.toString();
}
/**
*我们根据您的要求丢弃钥匙
*/
@凌驾
受保护的文本generateActualKey(文本键、文本值){
返回null;
}
}
编译步骤:

  • 将文本准确地保存到文件中(没有其他名称) CustomMultiOutputFormat.java
  • 当您在上面保存的文件所在的目录中时,键入-

    $JAVA_HOME/bin/javac-cp$(hadoop类路径)-d。CustomMultiOutputFormat.java

  • 在尝试之前,请确保JAVA_HOME设置为/path/to/your/SUNJDK 上面的命令

  • 使用(准确键入)创建custom.jar文件-

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

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

    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

  • 完成这些操作后,您应该会在输出路径中看到两个目录,一个是有效的文件名,另一个是错误文件名。所有具有有效\u file\u名称作为标记的记录都将转到有效的\u file\u名称目录,所有具有err\u file\u名称的记录都将转到err\u file\u名称目录


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

    你的问题很有趣。我试图回答。希望它有意义。请务必回复。谢谢我曾希望通过流式API(无需定义自定义输出格式)在纯python中实现这一点,但正如您所说,我认为这实际上是不可能的。谢谢你提供了一个真正的解决方案!是的,对于Python来说,有很多方法可以使用,比如进行剥离和执行hadoop命令,但我认为这不是一个干净的好方法,不能满足您的需要。键和值之间的分隔符会发生什么变化?行的前面有它吗?请你解释一下generateFileNameForKeyValue方法中的leaf好吗?@slayton:分隔符在理想情况下不应该出现。如果您看到了这一点,可能可以将默认的键值分隔符重写为空字符串或其他内容。应该有这样一个属性。