当前位置: 首页 > 面试题库 >

使用Python映射器进行Hadoop流传输的多个输出文件

吴镜
2023-03-14
问题内容

我的用例如下:

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


问题答案:

您可以执行类似以下的操作,但是它涉及一些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

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

  2. 使用(精确键入)制作您的custom.jar文件-

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

  1. 最后,像这样运行您的工作-

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

完成这些操作后,您应该在 输出路径中 看到两个目录,一个目录带有 有效文件名 ,另一个目录具有 err_file_name
。所有具有有效文件名作为标记的记录都将进入valid_file_name目录,而所有具有err_file_name的记录将进入err_file_name目录。

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



 类似资料:
  • 我遇到了一个非常非常奇怪的问题。还原器确实工作,但如果我检查输出文件,我只能找到映射器的输出。当我尝试调试时,在将映射器的输出值类型从Longwritable更改为Text之后,我发现了与单词计数示例相同的问题 这是结果。 然后我在输出文件中发现了奇怪的结果。这个问题发生在我将map的输出值类型和reducer的输入键类型更改为Text之后,无论我是否更改了reduce输出值的类型。我还被迫更改j

  • 我是Hadoop的新手,但这是我上个月的一个学习项目。 为了使这一点足够模糊,以便对其他人有用,让我先抛出基本目标……假设: < li >显然,您有一个大型数据集,包含数百万个基本ASCII文本文件。 < ul > < li >每个文件都是一个“记录” e. g. /user/hduser/data/customer1/YYYY-MM-DD, /user/hduser/data/customer2

  • 我正在从mapper生成两个输出文件。我使用Multipleoutput api生成两个输出。我不确定这样做是否正确。这是我的代码。。请仔细检查一下,给我你的建议。。当我运行代码时,我得到了一个错误:java。lang.NullPointerException。。 这是日志... 错误:java。com上的lang.NullPointerException。尼尔森。grfe。Export\u Co

  • 在java中,我会使用: 多输入.add输入路径(conf, path, inputFormatClass, 映射器类) 以添加多个输入,并为每个输入使用不同的映射器。 现在我正在使用python在hadoop中编写一个流作业,可以做类似的工作吗?

  • 我使用的是hadoop版本0.20和hadoop-core:1.2.0.jar 有没有可能使用新的hadoop API做到这一点?

  • 问题内容: 我正在尝试将我的reducer的结果输出到多个文件。数据结果全部包含在一个文件中,其余结果根据它们所尊重的文件中的类别进行划分。我知道使用0.18可以使用MultipleOutputs做到这一点,并且它尚未被删除。但是,我正在尝试使我的应用程序兼容0.20+。现有的多输出功能仍然需要JobConf(我的应用程序使用Job和Configuration)。如何根据密钥生成多个输出? 问题答