我有两个独立的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作业。我也想知道如何将输出文件写入两个不同的文件夹。目前,两个作业都是独立的,需要输入和输出目录。
答案 0 :(得分:12)
您可以拥有多个映射器,但在一个作业中,您只能拥有一个reducer。您需要的功能是MultipleInput
,MultipleOutput
和GenericWritable
。
使用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。