【问题标题】:Hadoop MapReduce - one output file for each inputHadoop MapReduce - 每个输入一个输出文件
【发布时间】:2012-01-16 21:08:24
【问题描述】:

我是 Hadoop 的新手,我正在尝试弄清楚它是如何工作的。至于练习,我应该实现类似于 WordCount-Example 的东西。任务是读取几个文件,进行 WordCount 并为每个输入文件编写一个输出文件。 Hadoop 使用组合器并将 map-part 的输出打乱作为 reducer 的输入,然后写入一个输出文件(我猜是每个正在运行的实例)。我想知道是否可以为每个输入文件编写一个输出文件(所以保留 inputfile1 的单词并将结果写入 outputfile1 等等)。是否可以覆盖 Combiner-Class 或者是否有其他解决方案(我不确定这是否应该在 Hadoop-Task 中解决,但这是练习)。

谢谢...

【问题讨论】:

    标签: java hadoop mapreduce


    【解决方案1】:

    map.input.file 环境参数具有映射器正在处理的文件名。在映射器中获取此值并将其用作映射器的输出键,然后将单个文件中的所有 k/v 转到一个减速器。

    映射器中的代码。顺便说一句,我正在使用旧的 MR API

    @Override
    public void configure(JobConf conf) {
        this.conf = conf;
    }
    
    @Override.
    public void map(................) throws IOException {
    
            String filename = conf.get("map.input.file");
            output.collect(new Text(filename), value);
    }
    

    并使用 MultipleOutputFormat,这允许为作业编写多个输出文件。文件名可以从输出的键和值派生出来。

    【讨论】:

    • 谢谢,我认为这是最好的主意。也许我会使用旧的 API,因为它看起来更容易处理,但首先我会看看 0.20
    【解决方案2】:

    Hadoop 将数据“分块”成配置大小的块。默认为 64MB 块。您可能会看到这会导致您的方法出现问题;每个映射器可能只得到一个文件的一部分。如果文件小于 64MB(或配置的任何值),则每个映射器将仅获得 1 个文件。

    我有一个非常相似的约束;我需要一组文件(链中前一个 reducer 的输出)完全由单个映射器处理。我在我的解决方案中使用

    我让启动 MR 的进程写出文件的文件名以处理成单个文件。这些文件的写入位置是输入目录。由于每个文件小于 64MB,因此将为每个文件生成一个映射器。 map 进程将只被调用一次(因为文件中只有 1 个条目)。
    然后我将传递给映射器的值打开,然后进行我需要做的任何映射。 由于 hadoop 试图对它如何执行 Map/Reduce 过程进行智能处理,因此可能需要指定要使用的 reducer 的数量,以便每个 mapper 转到单个 reducer。这可以通过mapred.reduce.tasks 配置进行设置。我通过job.setNumReduceTasks("mapred.reduce.tasks",[NUMBER OF FILES HERE]); 进行此操作

    我的流程有一些额外的要求/限制可能使这个特定的解决方案很有吸引力;但对于 1:in 到 1:out 的示例;我已经完成了,上面已经列出了基础知识。

    HTH

    【讨论】:

    • 感谢您的意见。使用 setNumReduceTasks,我可以根据需要获得尽可能多的输出文件。然而,reducers 的输入仍然被混合/打乱。我确实检查了我的映射器的输出,似乎一个映射器正在处理两个文件(但这不应该是问题)。但是,仅处理一个文件的映射器的结果也会与其他映射器的结果混合在一起。我可以阻止 Hadoop 这样做(shuffle/combine?也许设置 combinerclass?)您是否刚刚获取所有文件名并将它们传递给映射器?还是我错过了什么?也许要设置另一个 conf 值?
    • 要强制使用特定的 reducer,请让每个映射器在写入输出时使用特定的键。相同的键将转到相同的映射器。您可以在 conf 中为每个作业传递不同的值,然后使用该值作为键。这将导致每个映射器的输出转到单个减速器(根据我的经验)。
    • 将文件名传递给映射器以便由单个映射器处理文件不是有效的方法。没有数据本地化,会有数据更加洗牌。解决的一种方法是将依赖文件捆绑到 1 (gz, tar) 并从 FileInputFormat#isSplitable 方法返回 false。
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多