mapreduce二次排序

一、二次排序发生在需要对 Key 排序的同时再对 Value 进行排序的情况下。
主要分为以下几个阶段:

Map 起始阶段

在Map阶段,使用 job.setInputFormatClass() 定义的 InputFormat ,将输入的数据集分割成小数据块 split,同时 InputFormat 提供一个 RecordReader的实现。本课程中使用的是 TextInputFormat,它提供的 RecordReader 会将文本的行号作为 Key,这一行的文本作为 Value。这就是自定义 Mapper 的输入是 < LongWritable,Text> 的原因。 然后调用自定义 Mapper 的map方法,将一个个< LongWritable,Text>键值对输入给 Mapper 的 map方法。

Map 最后阶段

在 Map 阶段的最后,会先调用 job.setPartitionerClass() 对这个 Mapper 的输出结果进行分区,每个分区映射到一个Reducer。每个分区内又调用 job.setSortComparatorClass() 设置的 Key 比较函数类排序。 可以看到,这本身就是一个二次排序。如果没有通过 job.setSortComparatorClass() 设置 Key 比较函数类,则使用 Key 实现的 compareTo() 方法。我们既可以使用 IntPair 实现的 compareTo() 方法,也可以专门定义 Key 比较函数类。

Reduce 阶段

在 Reduce 阶段,reduce() 方法接受所有映射到这个 Reduce 的 map 输出后,也是会调用 job.setSortComparatorClass()方法设置的 Key 比较函数类,对所有数据进行排序。然后开始构造一个 Key 对应的 Value 迭代器。 这时就要用到分组,使用 job.setGroupingComparatorClass()方法设置分组函数类。只要这个比较器比较的两个 Key 相同,它们就属于同一组,它们的 Value 放在一个 Value 迭代器,而这个迭代器的 Key 使用属于同一个组的所有Key的第一个Key。最后就是进入 Reducer 的 reduce() 方法,reduce() 方法的输入是所有的 Key 和它的 Value 迭代器,同样注意输入与输出的类型必须与自定义的 Reducer 中声明的一致。

二、具体流程:

1、自定义 key

所有自定义的 key 应该实现接口 WritableComparable,因为它是可序列化的并且可比较的。

//反序列化,从流中的二进制转换成IntPair
public void readFields(DataInput in) throws IOException

//序列化,将IntPair转化成使用流传送的二进制
public void write(DataOutput out)

//key的比较
public int compareTo(IntPair o)

//默认的分区类 HashPartitioner,使用此方法
public int hashCode()

//默认实现
public boolean equals(Object right)

2、自定义分区

自定义分区函数类 FirstPartitioner,是 key 的第一次比较,完成对所有 key 的排序。

public static class FirstPartitioner extends Partitioner< IntPair,IntWritable>

在 job 中使用 setPartitionerClasss()方法设置 Partitioner。

job.setPartitionerClasss(FirstPartitioner.Class);

3、Key 的比较类

这是 Key 的第二次比较,对所有的 Key 进行排序,即同时完成IntPair中的first和second排序。该类是一个比较器,可以通过两种方式实现。

1) 继承 WritableComparator。

public static class KeyComparator extends WritableComparator

必须有一个构造函数,并且重载 以下方法。

public int compare(WritableComparable w1, WritableComparable w2)

2) 实现接口 RawComparator。
上面两种实现方式,在 Job 中,可以通过setSortComparatorClass()方法来设置Key的比较类。

job.setSortComparatorClass(KeyComparator.Class);

如果没有使用自定义的 SortComparator 类,则默认使用 Key 中compareTo()方法对 Key 排序分组。

4、定义分组类函数
在 Reduce 阶段,构造一个与 Key 相对应的 Value 迭代器的时候,只要 first 相同就属于同一个组,放在一个 Value 迭代器。定义这个比较器,可以有两种方式。

1) 继承 WritableComparator。

public static class GroupingComparator extends
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值