示例

数据:

-- ::    34c
-- :: 36c
-- :: 32c
-- :: 37c
-- :: 23c
-- :: 45c
-- :: 50c
-- :: 33c
-- :: 41c
-- :: 27c
-- :: 45c
-- :: 46c
-- :: 47c

要求:

将每年每月中的气温排名前三的数据找出来

实现:

1.每一年用一个reduce任务处理;

2.创建自定义数据类型,存储 [年-月-日-温度];

2.自己实现排序函数 根据 [年-月-温度] 降序排列,也可以在定义数据类型中进行排序;

3.自己实现分组函数,对 [年-月] 分组,reduce的key是分组结果,根据相同的分组值,统计reduce的value值,只统计三个值就可以,因为已经实现了自排序函数。

注意点:

1.自定义数据类型的使用;

2.自定义排序类的使用;

3.自定义分组类的使用,分组类对那些数据进行分组;

4.自定义分区类,分区类与reduce job个数的关系;

示例代码:

RunJob.java

 import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; /**
* weather 统计天气信息
*
* 数据:
* 1999-10-01 14:21:02 34c
* 1999-11-02 13:01:02 30c
*
* 要求:
* 将每年的每月中气温排名前三的数据找出来
*
* 实现:
* 1.每一年用一个reduce任务处理;
* 2.创建自定义数据类型,存储 [年-月-日-温度];
* 2.自己实现排序函数 根据 [年-月-温度] 降序排列,也可以在定义数据类型中进行排序;
* 3.自己实现分组函数,对 [年-月] 分组,reduce的key是分组结果,根据相同的分组值,统计reduce的value值,只统计三个值就可以,因为已经实现了自排序函数。
*
* Created by Edward on 2016/7/11.
*/
public class RunJob { public static void main(String[] args)
{
//access hdfs's user
System.setProperty("HADOOP_USER_NAME","root"); Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://node1:8020"); try {
FileSystem fs = FileSystem.get(conf); Job job = Job.getInstance(conf);
job.setJarByClass(RunJob.class);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class); //需要指定 map out 的 key 和 value
job.setOutputKeyClass(InfoWritable.class);
job.setOutputValueClass(Text.class); //设置分区 继承 HashPartitioner
job.setPartitionerClass(YearPartition.class);
//根据年份创建指定数量的reduce task
job.setNumReduceTasks(3); //设置排序 继承 WritableComparator
//job.setSortComparatorClass(SortComparator.class); //设置分组 继承 WritableComparator 对reduce中的key进行分组
job.setGroupingComparatorClass(GroupComparator.class); FileInputFormat.addInputPath(job, new Path("/test/weather/input")); Path path = new Path("/test/weather/output");
if(fs.exists(path))//如果目录存在,则删除目录
{
fs.delete(path,true);
}
FileOutputFormat.setOutputPath(job, path); boolean b = job.waitForCompletion(true);
if(b)
{
System.out.println("OK");
} } catch (Exception e) {
e.printStackTrace();
}
} public static class MyMapper extends Mapper<LongWritable, Text, InfoWritable, Text > { private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] str = value.toString().split("\t"); try {
Date date = sdf.parse(str[0]);
Calendar c = Calendar.getInstance();
c.setTime(date);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DAY_OF_MONTH); double temperature = Double.parseDouble(str[1].substring(0,str[1].length()-1)); InfoWritable info = new InfoWritable();
info.setYear(year);
info.setMonth(month);
info.setDay(day);
info.setTemperature(temperature); context.write(info, value); } catch (ParseException e) {
e.printStackTrace();
}
}
} public static class MyReducer extends Reducer<InfoWritable, Text, Text, NullWritable> {
@Override
protected void reduce(InfoWritable key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
int i=0;
for(Text t: values)
{
i++;
if(i>3)
break;
context.write(t, NullWritable.get());
}
}
}
}

InfoWritable.java

 import org.apache.hadoop.io.WritableComparable;

 import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; /**
* 自定义数据类型 继承 WritableComparable
* 【年-月-日-温度】
* Created by Edward on 2016/7/11.
*/
public class InfoWritable implements WritableComparable<InfoWritable> { private int year;
private int month;
private int day;
private double temperature; 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 setTemperature(double temperature) {
this.temperature = temperature;
} public int getYear() {
return year;
} public int getMonth() {
return month;
} public int getDay() {
return day;
} public double getTemperature() {
return temperature;
} /**
*
* 对象比较,对温度进行倒序排序
*/
@Override
public int compareTo(InfoWritable o) { int result = Integer.compare(this.getYear(),o.getYear());
if(result == 0)
{
result = Integer.compare(this.getMonth(),o.getMonth());
if(result == 0)
{
return -Double.compare(this.getTemperature(), o.getTemperature());
}
else
return result;
}
else
return result; //return this==o?0:-1;
} @Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeInt(this.year);
dataOutput.writeInt(this.month);
dataOutput.writeInt(this.day);
dataOutput.writeDouble(this.temperature);
} @Override
public void readFields(DataInput dataInput) throws IOException {
this.year = dataInput.readInt();
this.month = dataInput.readInt();
this.day = dataInput.readInt();
this.temperature = dataInput.readDouble();
}
}

YearPartition.java

 import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner; /**
*
* 创建分区,通过key中的year来创建分区
*
* Created by Edward on 2016/7/11.
*/
public class YearPartition extends HashPartitioner <InfoWritable, Text>{
@Override
public int getPartition(InfoWritable key, Text value, int numReduceTasks) {
return key.getYear()%numReduceTasks;
}
}

GroupComparator.java

 import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator; /**
* 创建分组类,继承WritableComparator
* 【年-月】
* Created by Edward on 2016/7/11.
*/
public class GroupComparator extends WritableComparator { GroupComparator()
{
super(InfoWritable.class, true);
} @Override
public int compare(WritableComparable a, WritableComparable b) {
InfoWritable ia = (InfoWritable)a;
InfoWritable ib = (InfoWritable)b; int result = Integer.compare(ia.getYear(),ib.getYear());
if(result == 0)
{
return Integer.compare(ia.getMonth(),ib.getMonth());
}
else
return result;
}
}

SortComparator.java

 import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator; /**
* 排序类,继承WritableComparator
* 排序规则【年-月-温度】 温度降序
* Created by Edward on 2016/7/11.
*/
public class SortComparator extends WritableComparator { /**
* 调用父类的构造函数
*/
SortComparator()
{
super(InfoWritable.class, true);
} /**
* 比较两个对象的大小,使用降序排列
* @param a
* @param b
* @return
*/
@Override
public int compare(WritableComparable a, WritableComparable b) { InfoWritable ia = (InfoWritable)a;
InfoWritable ib = (InfoWritable)b; int result = Integer.compare(ia.getYear(),ib.getYear());
if(result == 0)
{
result = Integer.compare(ia.getMonth(),ib.getMonth());
if(result == 0)
{
return -Double.compare(ia.getTemperature(), ib.getTemperature());
}
else
return result;
}
else
return result;
}
}

MapReduce -- 统计天气信息的更多相关文章

  1. 半吊子学习Swift--天气预报程序-获取天气信息

    昨天申请的彩云天气Api开发者今天上午已审核通过  饭后运动过后就马不停蹄的来测试接口,接口是采用经纬度的方式来获取天气信息,接口地址如下 https://api.caiyunapp.com/v2/ ...

  2. 内网公告牌获取天气信息解决方案(C# WebForm)

    需求:内网公告牌能够正确显示未来三天的天气信息 本文关键字:C#/WebForm/Web定时任务/Ajax跨域 规划: 1.天定时读取百度接口获取天气信息并存储至Txt文档: 2.示牌开启时请求Web ...

  3. 使用小米天气API获取天气信息

    1. URL部分 以下url中"%s"代表的是城市Id,比如北京的cityId=101010100: //获取未来五天预报信息,红色部分信息不需要 WEATHER_DATA_URL ...

  4. C#调用WebService获取天气信息

    概述 本文使用C#开发Winform应用程序,通过调用<WebXml/>(URL:http://www.webxml.com.cn)的WebService服务WeatherWS来获取天气预 ...

  5. ASP获取json天气信息

    ASP代码(ASP获取页面源码方法,有编码.超时时间参数,处理了乱码.超时的问题): Function GetHttpPage(HttpUrl) Then GetHttpPage="$Fal ...

  6. java获取天气信息

    通过天气信息接口获取天气信息,首先要给项目导入程序所需要的包,具体需要如下几个包: json-lib-2.4.jar ezmorph-1.0.6.jar commons-beanutils-1.8.3 ...

  7. 利用json获取天气信息

    天气预报信息获取是利用json获取的,网上有非常多资源,源码.因为上面涉及到非常多天气信息,包含湿度,出行建议等,以及加入了全部城市代码的资源包.为了练手了解json的原理.我仅获取诚笃城市的最高温, ...

  8. PHP Ajax JavaScript Json 实现天气信息获取

    使用第三方服务 间接方式 思路 使用到的服务 实现代码 前端完整代码 总结 要在自己的网站上添加一个天气预报功能,是一个很普通的需求,实现起来也不是很难.今天来介绍几个简单的方法. 使用第三方服务 有 ...

  9. MongoDb 用 mapreduce 统计留存率

    MongoDb 用 mapreduce 统计留存率(金庆的专栏)留存的定义采用的是新增账号第X日:某日新增的账号中,在新增日后第X日有登录行为记为留存 输出如下:(类同友盟的留存率显示)留存用户注册时 ...

随机推荐

  1. React—Native开发之原生模块向JavaScript发送事件

    首先,由RN中文网关于原生模块(Android)的介绍可以看到,RN前端与原生模块之 间通信,主要有三种方法: (1)使用回调函数Callback,它提供了一个函数来把返回值传回给JavaScript ...

  2. 活字格企业 Web 应用生成器新手上路指南

    活字格是一款企业 Web 应用生成器,使用了类 Excel 的设计界面,通过简单的拖拽操作,就能快速制作出一个 Web 信息管理系统.在整个使用过程中无需专业软件知识,没有任何技术门槛,能轻松实现各行 ...

  3. ifup / ifdown eth0 / eno1 reports unknown interface when it exists!

    li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style-type:lower-lati ...

  4. javascript的继承实现

    javascript虽然是一门面向对象的语言,但是它的继承机制从一开始设计的时候就不同于传统的其他面向对象语言,是基于原型的继承机制,但是在这种机制下,继承依然有一些不同的实现方式. 方法一:类式继承 ...

  5. CVE-2018-10945 mongoose越界访问

    Hello , I found a vulneratility in mg_handle_cgi function The function is in mongoose.c , line 8925  ...

  6. 1java异常详解

    语法错误.编译时错误语义错误.逻辑错误.运行时错误 数组下标越界,c,c++不检查,需要程序员控制. 1.注意:这里说的异常是运行期错误,不包括编译期错误. 2.try尝试运行,catch捕获并处理, ...

  7. 关于p标签

    说p标签是不能嵌套div和p的,嵌套会被浏览器解析分离.但如果你使用了document.createElement创建div,再appendChild的话反而可以了.看来浏览器并不支持动态解析

  8. sql server单个字段列转行由,隔开

    SELECT STUFF((SELECT ','+字段名 FROM 表名 for xml path('')),1,1,'')

  9. Jquery 保留N位小数,且千位以上用","号隔开

    s:数据Value n:保留小数位数 function jinEFmoney(s, n) { if (s == '' || s == null) return '0.00'; n = n > 0 ...

  10. 一些centos 6和centos 7的区别

      CentOS 6(OLE 6,RHEL 6类似) CcnetOS 7(OLE 7,RHEL 7类似) 影响 默认文件系统 ext4 xfs 大量小文件在ext4上工作性能较好在64位linux中, ...