我通过以下方式链接了mapreduce作业: map1 - > reduce1 - > map2 - >降低2 在map1步骤中作为副作用我计算仅在reduce2步骤中需要的数据,所以我不想将它一直传递到链中。传递此数据的最佳方法是什么,以便在reduce2步骤中我可以从map2和map1获取数据?
由于
答案 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);
其中MultipleInputs
为import org.apache.hadoop.mapred.lib.MultipleInputs;
。
您无法在reducer 2中获取数据并以与处理mapper 2输出相同的方式处理它们,除非您也使用映射器。通常,如果没有映射器,则无法使用reducer。最接近的是使用IdentityMapper。
如果您想以另一种方式处理 B ,那么,您可以通过分布式缓存获取它们,或者如果它是一个或两个数字,只需使用此值设置变量,使用conf.set("variableName", variableValue);
。然后,您可以使用setup()
在reducer 2的conf.get("variableName", defaultValue);
方法中获取此值。