Hadoop:在连续的mapreduce任务之间传递数据

时间:2014-10-17 10:46:27

标签: java hadoop mapreduce

我通过以下方式链接了mapreduce作业: map1 - > reduce1 - > map2 - >降低2 在map1步骤中作为副作用我计算仅在reduce2步骤中需要的数据,所以我不想将它一直传递到链中。传递此数据的最佳方法是什么,以便在reduce2步骤中我可以从map2和map1获取数据?

由于

1 个答案:

答案 0 :(得分:1)

根据您的评论,您从mapper 1输出 A B 。然后,您希望 A 转到reducer 1和< em> B 转到reducer 2,以及mapper 2的输出。 我能看到的最佳选择如下:

工作1:
要区分 A B ,请在第一个作业中使用MultipleOutputs ...对类型 B使用公共前缀(例如,在值中) 映射器1的中间输出,它将它们与 A 类型输出区分开来。在reducer 1中,当您看到前缀时,将其删除并在 B 输出路径中写入 B

工作2:
在第二份工作中使用MultipleInputs。将mapper 2用于它处理的输入,使用IdentityMapper用于 B 。这只是将 B 转发到reducer 2,您还将处理mapper 2的输出。

一个简单的代码段:

MultipleInputs.addInputPath(conf, new Path("/input/path/of/job/2"), SequenceFileInputFormat.class, Mapper2.class);
MultipleInputs.addInputPath(conf, new Path("/path/of/B"), SequenceFileInputFormat.class, IdentityMapper.class);

conf.setReducerClass(Reducer2.class); 

其中MultipleInputsimport org.apache.hadoop.mapred.lib.MultipleInputs;

您无法在reducer 2中获取数据并以与处理mapper 2输出相同的方式处理它们,除非您也使用映射器。通常,如果没有映射器,则无法使用reducer。最接近的是使用IdentityMapper。

如果您想以另一种方式处理 B ,那么,您可以通过分布式缓存获取它们,或者如果它是一个或两个数字,只需使用此值设置变量,使用conf.set("variableName", variableValue);。然后,您可以使用setup()在reducer 2的conf.get("variableName", defaultValue);方法中获取此值。