使用Python Mapper的Hadoop流的多个输出文件
我想在这里澄清一下这个问题的答案: 我的用例如下所示: 我有一个map-only mapreduce作业,它接受一个输入文件,进行大量解析和搜索,然后写回。但是,某些行的格式可能不正确,如果是这样,我想将原始行写入一个单独的文件 这样做的一种方法似乎是将文件名前置到我正在打印的行,并使用multipleOutputFormat参数。例如,如果我最初有:使用Python Mapper的Hadoop流的多个输出文件,python,hadoop,Python,Hadoop,我想在这里澄清一下这个问题的答案: 我的用例如下所示: 我有一个map-only mapreduce作业,它接受一个输入文件,进行大量解析和搜索,然后写回。但是,某些行的格式可能不正确,如果是这样,我想将原始行写入一个单独的文件 这样做的一种方法似乎是将文件名前置到我正在打印的行,并使用multipleOutputFormat参数。例如,如果我最初有: if line_is_valid(line): print name + '\t' + comments 我可以这样做: if li
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;
}
}
编译步骤:
$JAVA_HOME/bin/javac-cp$(hadoop类路径)-d。CustomMultiOutputFormat.java
$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
我希望所有这些都有意义。你的问题很有趣。我试图回答。希望它有意义。请务必回复。谢谢我曾希望通过流式API(无需定义自定义输出格式)在纯python中实现这一点,但正如您所说,我认为这实际上是不可能的。谢谢你提供了一个真正的解决方案!是的,对于Python来说,有很多方法可以使用,比如进行剥离和执行hadoop命令,但我认为这不是一个干净的好方法,不能满足您的需要。键和值之间的分隔符会发生什么变化?行的前面有它吗?请你解释一下generateFileNameForKeyValue方法中的leaf好吗?@slayton:分隔符在理想情况下不应该出现。如果您看到了这一点,可能可以将默认的键值分隔符重写为空字符串或其他内容。应该有这样一个属性。