参考答案:
1、简述
默认情况下,Map 输出的结果会对 Key 进行默认的排序,但是有时候需要对 Key 排序的同
时还需要对 Value 进行排序,这时候就要用到二次排序了。
2、详细过程
1)Map 起始阶段
在 Map 阶段,使用 job.setInputFormatClass()定义的 InputFormat,将输入的数据集分割成小数据块 split,同时 InputFormat 提供一个 RecordReader 的实现。在这里我们使用的是TextInputFormat,它提供的 RecordReader 会将文本的行号作为 Key,这一行的文本作为Value。这就是自定 Mapper 的输入是 的原因。然后调用自定义 Mapper 的 map 方法,将一个个键值对输入给 Mapper 的 map 方法
2)Map 最后阶段
在 Map 阶段的最后,会先调用 job.setPartitionerClass()对这个 Mapper 的输出结果进行分区,每个分区映射到一个 Reducer。每个分区内又调用 job.setSortComparatorClass()设置的 Key比 较 函 数 类 排 序 。 可 以 看 到 , 这 本 身 就 是 一 个 二 次 排 序 。 如 果 没 有 通 过job.setSortComparatorClass()设置 Key 比较函数类,则使用 Key 实现的 compareTo()方法
3)Reduce 阶段
在 Reduce 阶段,reduce()方法接受所有映射到这个 Reduce 的 map 输出后,也会调用job.setSortComparatorClass()方法设置的 Key 比较函数类,对所有数据进行排序。然后开始构 造 一 个 Key 对 应 的 Value 迭 代 器 。 这 时 就 要 用 到 分 组 , 使 用job.setGroupingComparatorClass()方法设置分组函数类。只要这个比较器比较的两个 Key 相同,它们就属于同一组,它们的 Value 放在一个 Value 迭代器,而这个迭代器的 Key 使用属于同一个组的所有 Key 的第一个 Key。最后就是进入 Reducer 的 reduce()方法,reduce()方法的输入是所有的 Key 和它的 Value 迭代器,同样注意输入与输出的类型必须与自定义的Reducer 中声明的一致
欢迎来撩 : 汇总all