shuffle的分组
map——shuffle——-reduce
shuffle:分区——排序——分组分组到底是怎么分组的:按照map的key进行分组的
默认的类型
对Reduce的结果进行打印输出。
wc:000000000000000000000000000hadoop----------------64hadoop----------------64hadoop----------------64hadoop----------------64000000000000000000000000000hadoophello----------------1hadoophello----------------1hadoophello----------------1hadoophello----------------1相同的key为一组默认的是key一直随着value指针变化而变化的 只不过默认的key都是一样的
自定义的类型:按照自定义类型的comparaTo的方法进行分组的
现根据:科目,再根据成绩,会将相同科目和相同分数的人划分到一组111111111111111111111111111111computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)map:context.write(sb,null)computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)
reduce:默认分组:调用的就是所有类型ComparaTo方法—-排序的方法
有的需求中分组和排序如果有冲突,怎么办?
分组和排序冲突
如:求出每门课程中参加考试的学生平均成绩的top3的学生的信息:课程,姓名和平均分
课程 姓名 成绩computer liujialing 98computer huangbo 96computer liutao 95math huangdatou 99math liuyifei 98math liutao 95map的输出的key:自定义类型(课程 姓名 成绩)排序:按照成绩分组:课程comparaTo(){先按课程成绩}但是实际的上的分组是根据comparaTo()方法,按照:课程+成绩相同的划分为一组每个课程的前三:要求:保证reduce一次性可以接受的数据是同一门课程的实际:(课程+成绩)相同的划分为一组结果:排序和分组冲突了解决:分组不能使用刚才的排序的规则的了,需要自定义分组排序:按照成绩分组:课程自定义分组:分组:课程分组的底层:对map输出所有的key进行比较:- 相同的key (return 0)就认为一组- 比较的过程中,返回的(!= 0)就认为不是同一组
自定义分组
writableComparator普通类,定义分组规则的。
默认的分组的比较:@SuppressWarnings("unchecked")//map输出的key-----具有比较和序列化能力(WritableComparable)//参数:WritableComparable//分组针对map输出的keypublic int compare(WritableComparable a, WritableComparable b) {//默认的分组就是调用的自定义的comparaToreturn a.compareTo(b);}
自定义分组:重写compare
继承writableComparator
重写compare()
job中指定
job.setGroupingComparatorClass(MyGroup.class);
常见报错
java.lang.Exception: java.lang.NullPointerException
空指针异常的错误:compare() 两个参数的对象默认不会帮我们创建的
/** Construct for a {@link WritableComparable} implementation. */protected WritableComparator(Class<? extends WritableComparable> keyClass) {this(keyClass, null, false);}protected WritableComparator(Class<? extends WritableComparable> keyClass,boolean createInstances) {this(keyClass, null, createInstances);}//参数1 比较的对象类型的class ScoreBean//参数2 配置文件对象//参数3---是否创建WritableComparable,这个对象默认false代表不创建protected WritableComparator(Class<? extends WritableComparable> keyClass,Configuration conf,boolean createInstances) {}
自定义分组例子
import org.apache.hadoop.io.WritableComparable;import org.apache.hadoop.io.WritableComparator;/*** 自定义分组* @author Administrator**/public class MyGroup extends WritableComparator{//写构造方法去调用父类,三个参数的最后一个参数要写成truepublic MyGroup() {//创建需要的比较对象super(ScoreBean.class,true);}//重写/*** 两个参数 代表两个比较对象 map的key*/@Overridepublic int compare(WritableComparable a, WritableComparable b) {//按照课程进行分组ScoreBean asb=(ScoreBean)a;ScoreBean bsb=(ScoreBean)b;return asb.getName().compareTo(bsb.getName());}}
结果文件
排序:分数分组:课程=========================computer huangjiaju 83.2-----------(null)computer huangjiaju 83.2-----------(null)computer liutao 83.0-----------(null)=========================math huangxiaoming 83.0-----------(null)=========================english huanglei 83.0-----------(null)=========================computer liutao 83.0-----------(null)没有显示3个的原因:先进行的排序,再进行的分组排完序:computer huangjiaju 83.2-----------(null)computer huangjiaju 83.2-----------(null)computer liutao 83.0-----------(null)math huangxiaoming 83.0-----------(null)english huanglei 83.0-----------(null)computer liutao 83.0-----------(null)分组在排序的基础上进行的:判断相邻的computer huangjiaju 83.2-----------(null)computer huangjiaju 83.2-----------(null)computer liutao 83.0-----------(null)-> 为一组math huangxiaoming 83.0-----------(null)-> 为一组english huanglei 83.0-----------(null)-> 为一组computer liutao 83.0-----------(null)排序的时候需要将分组的字段放在一起排序:课程,分数分组:课程
排序分组的组合
排序的字段中必须包含 分组字段,分组字段必须在排序字段的前面
既有排序 a,b 又有分组 c
- 排序:c a b
- 分组:c
补充
reduce中的迭代器:摄入量
1. 只能迭代一次,迭代的过程中是指针的操作> 只要迭代一次 指针调到末尾
- 迭代器中的数据对应的一组的所有的value
这个迭代器中每一个value都对应一个自己的key
输入reduce中的结果:
111111111111111111111111111111computer huangzitao 72.42857142857143computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)computer huangzitao 72.42857142857143-----------(null)computer huangxiaoming 72.42857142857143-----------(null)==============每一组中的这个key是一直随着value指针移动而移动的每一个value都会对应一个key值
