一、气温指数分析案例
1、需求
找出每个月气温最高的2天
2、数据准备
tianqi.txt
1949-10-01 14:21:02 34c
1949-10-01 19:21:02 38c
1949-10-02 14:01:02 36c
1950-01-01 11:21:02 32c
1950-10-01 12:21:02 37c
1951-12-01 12:21:02 23c
1950-10-02 12:21:02 41c
1950-10-03 12:21:02 27c
1951-07-01 12:21:02 45c
1951-07-02 12:21:02 46c
1951-07-03 12:21:03 47c
结果:
1949 10 1 38c
1949 10 2 36c
1950 1 1 32c
1950 10 2 41c
1950 10 1 37c
1951 7 3 47c
1951 7 2 46c
1951 12 1 23c
3、思路
每年
每个月
最高
2天
1天多条记录?
进一步思考:
年月分组
通过GroupCompartor设置分组规则,保证相同年月的分到同个组
温度降序的方式进入同个组,
通过SortComparator二次排序
遍历所有value,找出温度最高值,并记录对应天,
再找温度次高值,并且确保该次高值的天与温度最高值所对应的天不一样
最结果按照年月日排序
key中要包含时间和温度
自定义数据类型TianQi
包含时间
包含温度
自定义排序比较规则
自定义分组比较
年月相同被视为相同的key
那么reduce迭代时,相同年月的记录有可能是同一天的
reduce中需要判断是否同一天
注意OOM(内存溢出)
数据量很大
全量数据可以切分成最少按一个月份的数据量进行判断
这种业务场景可以设置多个reduce
通过实现partition
4、代码实现
a)TianQi
package com.bigdata.tianqi;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;
public class TianQi implements WritableComparable<TianQi>{
private int year ;
private int month;
private int day;
private int wd;
public TianQi() {
super();
// TODO Auto-generated constructor stub
}
public TianQi(int year, int month, int day, int wd) {
super();
this.year = year;
this.month = month;
this.day = day;
this.wd = wd;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getWd() {
return wd;
}
public void setWd(int wd) {
this.wd = wd;
}
public void write(DataOutput out) throws IOException {
out.writeInt(year);
out.writeInt(month);
out.writeInt(day);
out.writeInt(wd);
}
public void readFields(DataInput in) throws IOException {
year = in.readInt();
month = in.readInt();
day = in.readInt();
wd = in.readInt();
}
//按照年月日升序排序
public int compareTo(TianQi o) {
int c1 = Integer.compare(this.getYear(), o.getYear());
if(