我有两个独立的java类来做两个不同的mapreduce作业。我可以独立运行它们。它们所操作的输入文件对于这两个作业是相同的。所以我的问题是是否可以在一个 java 类中定义两个映射器和两个化简器,例如
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),然后处理两个mapreduce作业。我还想知道如何将输出文件写入两个不同的文件夹。目前,这两个作业是独立的,需要一个输入和一个输出目录。
您可以有多个映射器,但在一个作业中,您只能有一个化简器。您需要的功能是 MultipleInput
、 MultipleOutput
和 GenericWritable
.
使用 MultipleInput
,可以设置映射器和相应的输入格式。这是我关于如何使用它的帖子。
使用 GenericWritable
,可以在化简器中分离不同的输入类。这是我关于如何使用它的帖子。
使用 MultipleOutput
,可以在同一化简器中输出不同的类。
你可以为此使用 MultipleInputs 和 MultipleOutputs 类,但两个映射器的输出将转到两个化简器。 如果两个映射器/化简器对的数据流确实彼此独立,则将它们保留为两个单独的作业。 顺便说一下,MultipleInputs将在没有变化的情况下运行你的映射器,但必须修改化简器才能使用MultipleOutputs。
根据我的理解,这来自于将map-reduce与Hadoop流一起使用,你可以链接多个映射器和化简器,其中一个消耗另一个的输出
但是,您不应该能够同时运行不同的映射器和化简器。映射器本身依赖于要处理的块。映射器应根据该决策进行实例化,而不是基于可用于作业的映射器种类。
[编辑:根据您的评论]
我认为这是不可能的。您可以链接(其中化简器将从映射器接收所有输入。您可以对它们进行排序,但不能专门运行独立的映射器和化简器集。
我认为你可以做的是,即使你从映射器接收到两个化简器的输入,你也可以使映射器输出(K,V)是这样一种方式,你可以在你的化简器中区分哪个映射器是(K,V)的原点。这样,两个化简器都可以在选择性(K,V)对上进行处理。
ChainMapper 类允许在单个 Map 任务中使用多个 Mapper 类。例如,请看这里。