如何在单个MapReduce作业中实现多个Reducer

时间:2015-03-02 11:52:17

标签: hadoop mapreduce hadoop2

我有一个庞大的数据集,我需要为相同的数据执行不同的功能。     我想有四个输出文件。由于四个操作不同,我可以使用四个分区和四个 reducer 来实现相同的操作吗?是否有可能或者我应该写四个工作来执行此操作?请帮帮我!

3 个答案:

答案 0 :(得分:2)

您只需在MapReduce中指定减少器的数量即可 工作配置。默认分区程序将根据指定Reducer的密钥模数的散列将数据分发给reducer。

要覆盖默认分区程序的行为,您可以实现自己的自定义分区程序,指定数据应如何传递到reducer。

---编辑以回答评论部分中的问题---

如何在Map-reduce驱动程序中指定多个reducer类

要设置减速器的数量,在作业配置中,您可以设置如下 -

int numReducers = /*number of reducers you want*/;
job.setNumReduceTasks(numReducers);

我是否应该为此写四个不同的工作。或者我可以使用单个作业执行此操作

Hadoop MR作业是I / O密集型的,在MR作业设计中,您应该尽可能地减少I / O和并行处理。

如果您的Reducer需要相同的输入来生成所有4个输出,那么保留单个作业会更好,但另一个考虑因素可能是任何一个输出的数据偏差。 例如,output1有更多的处理时间+大多数传入数据可能会被处理为output1。 如果你有像处理时间一样的场景输出1比处理输出2 +输出3 +输出4所花费的总时间要高得多,那么你应该考虑在多个步骤中拆分output1的处理。

但是,如果我们认为所有4次出局都有或多或少相等的处理时间并且在整个过程中消耗相同的数据, 在reducer中有一些条件处理逻辑会更好,让你的自定义分区决定哪些数据到哪个reducer。

您的自定义分区可以进行一些检查,例如此传入数据有资格参与“GC内容”,所以让它到达Reducer 3。 但是,如果需要处理多个输出/分配的输入数据,则使用条件处理并从同一个reducer中写入多个输出文件,使用“MultipleOutputs”。 您可以对其进行谷歌搜索并查找用法示例,它允许您在Mapper或Reducer中同时将输出写入多个文件夹/文件。

答案 1 :(得分:2)

第一种方法

我认为你应该在一个独特的reduce方法中实现代码,并根据执行的进程发出n个密钥。例如:您实现A,B,C和D技术,然后,在您的映射器中,您可以实现此(伪代码):

dataA = ProcessA(key,value)
context.write("A", dataA)
dataB = ProcessB(key,value)
context.write("B", dataB)
dataC = ProcessC(key,value)
context.write("C", dataC)
dataD = ProcessD(key,value)
context.write("D", dataD)

您应该注意输出的数据类型。此外,输出键可能更复杂。

第二种方法

您可以在同一个java项目中生成N个MapReduce应用程序,然后重新使用Map,并开发N个reducer。

在每个主要类中的job.setReducerClass中设置每个Reducer。地图将是相同的。

答案 2 :(得分:0)

Hadoop允许您从作业驱动程序 job.setNumReduceTasks(num_reducers); 中指定reducer任务的数量。由于您需要四个输出,因此您需要指定int num_reducers = 4;这是一个示例驱动程序类。

public class run {

    public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();
        Job job = new Job(conf, "Run NB Count");

        job.setJarByClass(NB_train_hadoop.class);
        // set mappers, reducers, other stuff
        job.setNumReduceTasks(num_reducers);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

虽然这很方便,但您必须明白,您可以选择最佳数量的reducer,这取决于群集中的节点数。

例如,运行4个Amazon m3.xlarge实例(1个主服务器,3个从服务器和4个核心实例),在挂起时间和MapReduce作业中使用的reducer任务数之间具有以下关系。你可以看到更多并不一定更好,如果你使用太多,那么你也可以用你母亲的卷发器来处理你的数据,因为这样会更快。

enter image description here

希望这有用!!