由于我是hadoop的新手,我尝试了http://www.tutorialspoint.com/map_reduce/map_reduce_partitioner.htm的示例代码。我发现该程序使用了基于年龄组的3个不同分区,并且还使用了3个减速器,这是预期的。但是在reducer代码中(这里性别是关键的男性/女性)我仍然得到,我认为这个值列表创建是由散列分区程序完成的。但是我已经定义了getPartitions(),谁创建了这个列表呢?
答案 0 :(得分:0)
在上面的示例代码中,我们在run方法 -
下面有驱动程序代码 Configuration conf = getConf();
Job job = new Job(conf, "topsal");
job.setJarByClass(PartitionerExample.class);
FileInputFormat.setInputPaths(job, new Path(arg[0]));
FileOutputFormat.setOutputPath(job,new Path(arg[1]));
job.setMapperClass(MapClass.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
//set partitioner statement
job.setPartitionerClass(CaderPartitioner.class);
job.setReducerClass(ReduceClass.class);
job.setNumReduceTasks(3);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
System.exit(job.waitForCompletion(true)? 0 : 1);
return 0;
在这里你可以看到它将CaderPartitioner类设置为上面MR的分区器。根据Map Reduce规范,如果我们的程序没有设置任何自定义分区程序,那么只有在这种情况下,身份分区才会出现。
因此,在上面的场景中,将发生CaderPartitioner并为上述MR执行分区。由于它有3个条件,它将输入键分为3个不同的组,并将这些组发送到不同的减速器,并相应地进行减速器。
希望这有帮助。
答案 1 :(得分:0)
如果你的工作有3个减速器,它们也会被整数索引:0,1和2.
getPartition()
方法的目的是将地图输出中的每个(键,值)对作为参数,并确定该对是否应该转到减速器0,1或2。这就是' s为什么getPartition()
方法的返回类型为 int 。
因此,所有映射输出(在被getPartition()
分析后)都会影响到Reducer 2,将被写入同一个分区,也被编入索引2.该分区将位于映射器内,等待reducer 2获取它。
你问谁创建了这个分区?根据我的发现,它是一个名为MapFileOutputFormat
的类,名为getEntry()
的方法。正如类名所示,可能是负责管理地图输出数据的类。
HashPartitioner
是默认分区程序,仅在您没有为作业定义任何分区程序时使用。它仅基于(key,value)对的密钥的哈希码,因此具有相同密钥的所有对(即相同的哈希码)最终都在同一个分区器中,这是MapReduce中的默认行为。
您在教程中提到的代码使用自定义分区程序,其getPartition()
方法的实现将年龄组与某些分区程序相关联。 (20岁以下去减速机0,20到30之间去减速机1等......)。
此自定义分区程序(CaderPatitioner
)是MapReduce作业的分区程序,因为它是使用job.setPartitionerClass()
设置的。作业中只有一个分区程序,因此HashPartitioner
从未在此作业中使用过,因此在您的情况下它绝对没有任何作用。
所以为了回答你的问题,如果我理解得很清楚,CaderPatitioner
负责决定如何将地图输出分成多个分区,然后这些分区将以不同的缩减器结束。