如何在同一输入上运行两个不同的映射器并将其输出发送到单个reducer?

时间:2015-03-29 15:25:18

标签: java hadoop join mapreduce

我有一些航班数据(每行包含出发地,目的地,航班号等),我需要处理它以输出所有起点和目的地之间的航班详情一次中途停留,我的想法是有两个映射器(一个输出目标作为键,另一个输出作为键,因此,reducer将中途停留位置作为键,所有原点和目标作为值数组)。然后我可以为减速器中的所有位置输出一次中途停留的航班详细信息。

所以我的问题是如何在同一输入文件上运行两个不同的映射器并将其输出发送到一个reducer。

我读到了MultipleInputs.addInputPath,但我想它需要输入不同(或至少两个相同输入的副本)。

我正在考虑使用工作流程独立运行两个映射器作业,然后使用第三个身份映射器和缩减器来执行飞行计算。

这有更好的解决方案吗? (请不要让我使用Hive,我还不熟悉)任何使用mapreduce实现的指导都会有所帮助。感谢。

2 个答案:

答案 0 :(得分:0)

您的问题没有说明您是否希望混合/匹配(中途停留/没有中途停留)。

所以我将继续讨论所陈述的问题:只考虑一次(非零)中途停留。

在这种情况下,只需要两个Map / Reduce阶段。第一阶段Mapper输出

(dest1, source1). 

第一级减速机接收     (dest1,Array(source1,source2,...)

然后第一级reducer将其元组写入hdfs输出目录。

现在进行第二阶段:映射器输入使用Stage1 reducer输出作为其源目录。

第二阶段映射器读取:

(dest1,Array(source1,source2,...))

第二阶段映射器输出:

 (dest2, (source1,dest1))

然后你的最终(stage2)减速器收到:

(dest2,  Array( (source11,dest11), (source12, dest12), (source13, dest13) ,...)

并将该数据写入hdfs输出。然后,您可以使用任何您喜欢的外部工具从hdfs中读取这些结果。

答案 1 :(得分:0)

我认为你只需要一个Mapper即可。

Mapper会发出两次(src,dst,fno,...)输入记录,一次为(src,(src,dst,fno,...)),一次为(dst,(src,dst,fno,...))。 在Reducer中,您需要确定每个记录的关键字是源还是目标,并进行中转连接。使用标志来指示密钥的角色和辅助排序可以使这更有效。

这样,任务中只需要一个具有一个Mapper和一个Reducer的MR作业。