Hadoop MapReduce:可以在一个hadoop作业类中定义两个映射器和缩减器吗?

时间:2012-06-20 15:23:47

标签: hadoop mapreduce

我有两个独立的java类用于执行两个不同的mapreduce作业。我可以独立运行它们。它们运行的​​输入文件对于这两个作业都是相同的。所以我的问题是是否可以在一个java类中定义两个映射器和两个reducer,如

mapper1.class
mapper2.class
reducer1.class
reducer2.class

然后喜欢

job.setMapperClass(mapper1.class);
job.setmapperClass(mapper2.class);
job.setCombinerClass(reducer1);
job.setCombinerClass(reducer2);
job.setReducerClass(reducer1);
job.setReducerClass(reducer2);

这些设置方法是否实际覆盖了以前的方法或添加新方法?我尝试了代码,但它执行了唯一的最新给定的类,这让我认为它会覆盖。但必须有办法做到这一点吗?

我之所以这样问是因为我只能读取输入文件一次(一次I / O),然后处理两个map reduce作业。我也想知道如何将输出文件写入两个不同的文件夹。目前,两个作业都是独立的,需要输入和输出目录。

4 个答案:

答案 0 :(得分:12)

您可以拥有多个映射器,但在一个作业中,您只能拥有一个reducer。您需要的功能是MultipleInputMultipleOutputGenericWritable

使用MultipleInput,您可以设置映射器和相应的inputFormat。以下是关于如何使用它的post

使用GenericWritable,您可以在reducer中分隔不同的输入类。以下是关于如何使用它的post

使用MultipleOutput,您可以在同一个reducer中输出不同的类。

答案 1 :(得分:1)

您可以使用MultipleInputs和MultipleOutputs类,但两个映射器的输出将同时用于两个reducer。如果两个映射器/减速器对的数据流确实彼此独立,则将它们保持为两个单独的作业。顺便说一下,MultipleInputs将运行你的映射器而不进行更改,但是为了使用MultipleOutputs,必须修改reducer

答案 2 :(得分:0)

根据我的理解,使用map-reduce和Hadoop流,你可以链接多个映射器和reducer,其中一个消耗另一个的输出

但是你不应该同时运行不同的映射器和缩减器。映射器本身依赖于不处理的块。 Mapper应该根据该决定进行实例化,而不是可用于该作业的各种映射器。

[编辑:根据您的评论]

我认为这是不可能的。你可以链接(减速器将接收来自映射器的所有输入。你可以对它们进行排序,但你不能专门运行独立的映射器和减速器组。

我认为你可以做的是,即使你同时从两个减速器接收到映射器的输入,你也可以使映射器输出(K,V)这样你可以在你的减速器中区分出来哪个映射器是(K,V)的起源。这样两个减速器都可以处理选择性(K,V)对。

答案 3 :(得分:0)

ChainMapper类允许在单个Map任务中使用多个Mapper类。例如,请查看here