由于我是 hadoop 新手,我尝试了http://www.tutorialspoint.com/map_reduce/map_reduce_partitioner.htm中的示例代码,我发现该程序使用 3 个基于年龄组的不同分区,并且还使用了 3 个减速器,其中是期待。但是在 reducer 代码中(这里的性别是男性/女性的关键)我仍然得到,我假设这个值列表是由哈希分区器完成的。但是正如我定义的 getPartitions() ,这个列表是谁创建的?
2 回答
getPartition() 方法的简单解释
如果您的作业有 3 个减速器,它们也由整数索引:0、1 和 2。
该getPartition()
方法的目的是将 map 输出的每个 (key, value) 对作为参数,并决定该对是否应该转到 reducers 0、1 或 2。这就是该getPartition()
方法的返回类型为int的原因。
因此(在被分析后getPartition()
)影响到 Reducer 2 的所有 map 输出将被写入同一个分区,索引也为 2。该分区将位于映射器内,等待 reducer 2 获取它。
你问谁创建了这个分区?这是一个名为 的类,在根据我的发现MapFileOutputFormat
调用的方法中。getEntry()
正如类名所暗示的,可能是一个负责管理地图输出数据的类。
这HashPartitioner
是默认分区器,仅在您没有为作业定义任何分区器时使用。它仅基于 (key,value) 对的键的哈希码,因此具有相同键(即相同哈希码)的所有对最终都在同一个分区器中,这是 MapReduce 中的默认行为。
在你的教程中
您在教程中引用的代码使用自定义分区器,该getPartition()
方法的实现将年龄组与某些分区器相关联。(20 岁以下进入减速机 0,20 到 30 岁进入减速机 1 等等......)。
这个自定义分区器 ( CaderPatitioner
) 是 MapReduce 作业的分区器,因为它是使用job.setPartitionerClass()
. 作业中只有一个分区器,因此HashPartitioner
在此作业中从未使用过,因此在您的情况下它绝对没有任何作用。
所以要回答你的问题,如果我理解得很好,CaderPatitioner
负责决定如何将映射输出分成分区,然后这些分区最终会出现在单独的 reducer 中。
在上面的示例代码中,我们在运行方法中有以下驱动程序代码——
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 个不同的组,并将这些单独的组发送到不同的减速器,减速器将相应地发生。
希望这可以帮助。