GroupingComparator 辅助排序
对Reduce阶段的key
根据某一个或几个字段进行分组
应用场景:在接收对象的key为bean
时,想让一个或者多个字段
相同(全属性字段值不同
)的key进入到同一个reducer方法时,可以采用分组排序。
GroupingComparator是在reduce阶段分组来使用的,由于reduce阶段,如果key 相同的一组,只取第一个key作为key,迭代所有的values。
如果reduce的key是自定义的bean,我们只需要bean里面的某个属性相同就认为这样的key是相同的,这是我们就需要之定义GroupCoparator来“欺骗”reduce了。
分组排序步骤:
- (1)自定义类继承WritableComparator
- (2)重写compare()方法
- (3)创建一个构造将比较对象的类传给父类
/**
* 利用reduce端的GroupingComparator来实现将一组bean看成相同的key
*
*/
public class ItemidGroupingComparator extends WritableComparator {
//传入作为key的bean的class类型,以及制定需要让框架做反射获取实例对象
protected ItemidGroupingComparator() {
super(OrderBean.class, true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
OrderBean abean = (OrderBean) a;
OrderBean bbean = (OrderBean) b;
//比较两个bean时,指定只比较bean中的orderid
return abean.getItemid().compareTo(bbean.getItemid());
}
}
自定义的分区器
public class ItemIdPartitioner extends Partitioner<OrderBean, NullWritable>{
@Override
public int getPartition(OrderBean bean, NullWritable value, int numReduceTasks) {
//相同id的订单bean,会发往相同的partition
//而且,产生的分区数,是会跟用户设置的reduce task数保持一致
return (bean.getItemid().hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
在jobDriver设置:
//在此设置自定义的Groupingcomparator类
job.setGroupingComparatorClass(ItemidGroupingComparator.class);
//在此设置自定义的partitioner类
job.setPartitionerClass(ItemIdPartitioner.class);
//根据分区的个数设置n
job.setNumReduceTasks(n);