我正在尝试使用一个作业在hadoop程序中的同一输入文件上运行2个独立的映射器。我希望两个映射器的输出都进入一个减速器。我遇到运行多个映射器的问题。我正在使用MultipleInputs类。通过运行两个映射器它工作正常,但昨天我注意到它只运行一个map函数,第二个MultipleInputs语句似乎覆盖了第一个。我没有发现任何改变代码突然显示这种不同的行为:(请帮我这个..主要功能是:
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf, "mapper accepting whole file at once");
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(IntWritable.class);
job.setJarByClass(TestMultipleInputs.class);
job.setMapperClass(Map2.class);
job.setMapperClass(Map1.class);
job.setReducerClass(Reduce.class);
job.setInputFormatClass(NLinesInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setMapOutputKeyClass(IntWritable.class);
** MultipleInputs.addInputPath(job, new Path("Rec"), NLinesInputFormat.class, Map1.class);
MultipleInputs.addInputPath(job, new Path("Rec"), NLinesInputFormat.class, Map2.class);**
FileOutputFormat.setOutputPath(job,new Path("testMulinput"));
job.waitForCompletion(true);
}
执行最后一个MultipleInputs语句中使用的Map类。就像在这里一样,Map2.class被执行。
答案 0 :(得分:2)
你将无法同时使用两个单独的Mapper
来读取同一个文件(至少不是没有你应该避免的一些恶意的黑客技巧)。
在任何情况下,您都无法为同一作业设置两个Mapper
类 - 后一次调用setMapperClass(class)
将始终覆盖前者。如果您需要同时运行两个Mapper
,则需要创建两个单独的作业,并确保群集上有足够的映射器可以同时运行它们(如果之后没有可用的话)第一份工作开始,第二份工作必须等待它完成,顺序而不是同时运行。)
但是,由于缺乏Mapper
并发运行的保证,请确保MapReduce作业的功能不依赖于它们的并发执行。
答案 1 :(得分:1)
两个映射器无法同时读取同一文件。
解决方案(解决方法): 创建输入文件的副本(在这种情况下,让重复的rec文件为rec1)。然后使用rec和mapper2将mapper1与rec1一起提供。
两个映射器都是并行执行的,因此您不必担心reducer输出,因为两个映射器输出都将被混洗,以便两个文件中的相同键转到相同的reducer。
所以输出就是你想要的。
希望这有助于面临类似问题的其他人。