在学习二次排序的过程中,觉得还是很复杂的,写一篇博客分享一下。
一、什么是二次排序?
二次排序就是对value值进行排序(本身value值是不会排序的)
二、例子分析
需求:
求1920-2020年100年间每年气温的最大值。
问题分析:
1、这100年的数据每年的气温数据量十分的大
2、如果在每次在reduce里面对整个气温找最大值的话很消耗时间
方案:
为了解决上述分析中的问题,在reduce之前,将所有的气温数据按年份从小到大排列,同一年份中,温度由又大到小排列,这样的话,reduce只要拿同一组中的第一个数据,就得到了当年的最高温度。
mapreduce流程图:
详细分析整个过程:
1、map从reader中读取数据。
package cn.hbmy.hdfs.mr.secondsorttemperature;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class SecondSortTemWCMapper extends Mapper <IntWritable,IntWritable,Combokey,NullWritable>{
@Override
protected void map(IntWritable key, IntWritable value, Context context) throws IOException, InterruptedException {
Combokey combokey = new Combokey();
combokey.setYear(key.get());
combokey.setTemp(value.get());
context.write(combokey,NullWritable.get());
}
}
2、由于MapReduce中,只对key,排序不对value排序,为了能够对value进行排序,自己定义一个combokey,成员变量包含key和value,也就是上图中的需要解决地方4 ,此时K由combokey代替,value为null。下面给出combokey的定义类:
package cn.hbmy.hdfs.mr.secondsorttemperature;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* 不仅要有可比较的接口,还要实现串行化的接口
* */
public class Combokey implements WritableComparable<Combokey> {
private int year;
private int temp;
public int getYear() {
return year;
}
public int getTemp() {
return temp;
}
public void setYear(int year) {
this.year = year;