统计每个年月下,温度最高的前两天
1.数据
2020-01-02 10:22:22 1c
2020-01-03 10:22:22 2c
2020-01-04 10:22:22 4c
2020-02-01 10:22:22 7c
2020-02-02 10:22:22 9c
2020-02-03 10:22:22 11c
2020-02-04 10:22:22 1c
2019-01-02 10:22:22 1c
2019-01-03 10:22:22 2c
2019-01-04 10:22:22 4c
2019-02-01 10:22:22 7c
2019-02-02 10:22:22 9c
2018-02-03 10:22:22 11c
2018-02-04 10:22:22 1c
2.需求分析
3.Weather
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class Weather implements WritableComparable {
private int year;
private int month;
private int day;
private int degree;//温度
@Override//按顺序读取
public void readFields(DataInput dataInput) throws IOException {
this.year = dataInput.readInt();
this.month = dataInput.readInt();
this.day = dataInput.readInt();
this.degree = dataInput.readInt();
}
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeInt(year);
dataOutput.writeInt(month);
dataOutput.writeInt(day);
dataOutput.writeInt(degree);
//java.lang.RuntimeException: java.io.EOFException ---序列化与反序列化不一致的问题
}
@Override
public int compareTo(Weather o) {
int t1 = Integer.compare(this.year, o.getYear());
if (t1 == 0) {
int t2 = Integer.compare(this.month, o.getMonth());
if (t2 == 0) {
return -Integer.compare(this.degree, o.getDegree());
}
return t2;
}
return t1;
}
public void setYear(int year) {
this.year = year;
}
public void setMonth(int month) {
this.month = month;
}
public void setDay(int day) {
this.day = day;
}
public void setDegree(int degree) {
this.degree = degree;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
public int getDegree() {
return degree;
}
@Override
public String toString() {
return "Weather{" +
"year=" + year +
", month=" + month +
", day=" + day +
", degree=" + degree +
'}';
}
}
4.WeatherMapper
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class WeatherMapper extends Mapper {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//根据分割符分割
String[] split = value.toString().trim().split("t");
if (split != null && split.length >= 2) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
try {
Date date = format.parse(split[0]);
calendar.setTime(date);
Weather weather = new Weather();
weather.setYear(calendar.get(Calendar.YEAR));
weather.setMonth(calendar.get(Calendar.MONTH) + 1);//注意:月份从0开始计数的
weather.setDay(calendar.get(Calendar.DAY_OF_MONTH));
int degree = Integer.parseInt(split[1].substring(0, split[1].lastIndexOf("c")));
weather.setDegree(degree);
context.write(weather, new IntWritable(degree));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
5.WeatherPartition
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.mapreduce.Partitioner;
public class WeatherPartition extends Partitioner {
@Override
public int getPartition(Weather weather, IntWritable intWritable, int numPartitions) {//numPartitions由job.setNumReduceTasks(3)决定
//写一个算法计算hash,这个算法要满足业务需求,每一个键值都会调用此方法,所以该方法需要简洁
System.out.println((weather.getYear() - 1929) % numPartitions);
return (weather.getYear() - 1929) % numPartitions;
}
}
6.WeatherGroup
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class WeatherGroup extends WritableComparator {
public WeatherGroup() {
super(Weather.class, true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
Weather weather1 = (Weather) a;
Weather weather2 = (Weather) b;
int c1 = Integer.compare(weather1.getYear(), weather2.getYear());
if (c1 == 0) {
int c2 = Integer.compare(weather1.getMonth(), weather2.getMonth());
return c2;
}
return c1;
}
}
7.WeatherReduce
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class WeatherReduce extends Reducer {
@Override
protected void reduce(Weather key, Iterable values, Context context) throws IOException, InterruptedException {
int count = 0;
for (IntWritable i : values) {
count++;
if (count >= 3) {
break;
}
String res = key.getYear() + "-" + key.getMonth() + "-" + key.getDay() + "t" + i.get();
context.write(new Text(res), NullWritable.get());
}
}
}
8.WeatherMain
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
public class WeatherMain {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance();//创建job实例
job.setJarByClass(WeatherMain.class);
//1.map
job.setMapperClass(WeatherMapper.class);
//输出类型除了Text最好都设置一下,否则没有输出的
job.setMapOutputKeyClass(Weather.class);
job.setMapOutputValueClass(IntWritable.class);
//2.分区
job.setPartitionerClass(WeatherPartition.class);
//设置reduce数目
job.setNumReduceTasks(3);//output输出三个文件夹
//3.排序
//job.setSortComparatorClass(WeatherSort.class);
//4.reduce内部分组
job.setGroupingComparatorClass(WeatherGroup.class);
//5.reduce
job.setReducerClass(WeatherReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
FileInputFormat.addInputPath(job, new Path("E:\HadoopMRData\input"));//输入目录
Path outPath = new Path("E:\HadoopMRData\output");
FileOutputFormat.setOutputPath(job, outPath);
System.exit(job.waitForCompletion(true) ? 0 : 1);//启动,0表示正常退出
}
}