MapReduce分析年气象数据平均温度与最高温度(云计算实验作业20180523)


课程原地址:http://hbust.shiyanbar.com/course/91079

上课老师:李歆

实验时间:20180523

地点:云桌面

实验人:郭畅

 

【实验目的】

1) 理解mapreduce执行原理

2) 理解map,reduce阶段

3) 熟悉mapreduce代码的编写

【实验原理】

把采集的气象数据信息以日志的方式保存到指定的位置,该位置可以是本地,也可以是hdfs分布式系统上,利用hadoop计算技术对该日志文件进行处理,主要分两个阶段:mapper阶段和reducer阶段,mapper阶段主要是对日志文件进行按行读取并进行字符串截取,reducer阶段对mapper阶段传过来的数据进行大小比较,最终获取每一年中的最高温度。

气象采集数据格式如下:

0067011990999991950051507004888888889999999N9+00001+9999999999999999999999

0067011990999991950051512004888888889999999N9+00221+9999999999999999999999

0067011990999991950051518004888888889999999N9-00111+9999999999999999999999

0067011990999991949032412004888888889999999N9+01111+9999999999999999999999

数据说明:

15-19个字符是year

45-50位是温度表示,+表示零上 -表示零下,且温度的值不能是99999999表示异常数据。

50位值只能是01459几个数字

【实验环境】

本次环境是:centos6.5 + jdk1.7.0_79 + hadoop2.4.1 + eclipse

日志文件source.txt存放在桌面名为`分布式计算MapReduce开发基础`目录下的相应章节中对应的实验名下的文件夹中找寻。

jar包在桌面名为`lib`文件夹下。

【实验步骤】

一、项目准备阶段

1.1 linux系统的命令终端上切换到/simple目录,执行命令:touch source.txt创建一个文件。如图1所示

 

1

 

1.2 simple目录下,执行命令:vi /simple/source.txt编辑该文件,并把采集的气象信息内容拷贝到该文件中,然后在simple目录可以查看到source.txt文件。如图2所示

 

2

1.3 本案例因为需要用到hadoop的计算,所以在编写程序之前需要先启动yarn服务,可以在命令终端执行命令:start-all.sh hdfsyarn服务启动。(查看服务启动共有6项,如果缺少请执行stop-all.sh关闭,重新启动)。如图3所示


3

 

二 程序编写

2.1 eclipse中的项目列表中,右键点击,选择“new“—>Java Project…”新建一个项目“TemperatureAvg” 。 如图4所示

 

4

 

2.2 在项目src目录下,右键点击,选择“新建”创建一个类文件名称为“AvgTemperatureMapper”并指定包名”com.simple.temperature” 。如图5所示

 

5

 

2.3 在编写“AvgTemperatureMapper”类之前需要把hadoop相关的jar包导入,首先在项目根目录下创建一个文件夹lib并把指定位置中的包放入该文件中 。如图6所示

 

6

 

2.4 lib下所有的jar包导入到环境变量,首先全选lib文件夹下的jar包文件,右键点击,选择“build path-->add to build path,添加后,发现在项目下多一个列表项“Referenced Libraries”。如图7所示

 

7

 

 

2.5 让类“AvgTemperatureMapper”继承类Mapper同时指定需要的参数类型,根据业务逻辑修改map类的内容如下。

package com.simple.temperature;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Mapper;

public class AvgTemperatureMapper extends

Mapper<LongWritable, Text, Text, IntWritable> {

private static final int MISSING = 9999;

@Override

protected void map(LongWritable key, Text value,

Mapper<LongWritable, Text, Text, IntWritable>.Context context)

throws IOException, InterruptedException {

String line = value.toString();//读取一条记录

String year = line.substring(15, 19);//获取温度数

System.out.println("year=="+year);

int airTemperature;

if (line.charAt(45) == '+') { //判断温度正负

airTemperature = Integer.parseInt(line.substring(46, 50));

} else {

airTemperature = Integer.parseInt(line.substring(45, 50));

}

String quality = line.substring(50, 51);

System.out.println("quality: " + quality);

//判断温度是否异常

if (airTemperature != MISSING && quality.matches("[01459]")) {

context.write(new Text(year), new IntWritable(airTemperature));

}

}

} 

2.6 在项目src目录下指定的包名”com.simple.temperature”下右键点击,新建一个类名为“AvgTemperatureReducer “并继承Reducer类,然后添加该类中的代码内容如下所示。


package com.simple.temperature;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Reducer;

public class AvgTemperatureReducer extends Reducer

<Text, IntWritable, Text, IntWritable>{

@Override

protected void reduce(Text key, Iterable<IntWritable> values,

Context context)

throws IOException, InterruptedException {

//声明变量sumValue作为年温度和

int sumValue = 0;

//声明count作为统计同一年温度记录的次数

int count = 0;

//循环求同一年所有温度的和及温度记录次数

for(IntWritable value: values){

sumValue+=value.get();

count++;

}

int avgValue = sumValue/count;

context.write(key, new IntWritable(avgValue));

}

}

 


2.7 在项目src目录下指定的包名”com.simple.temperature”下右键点击,新建一个测试主类名为“AvgTemperature “并指定main主方法。如图8所示


8

 

 

2.8添加代码如下所示。


package com.simple.temperature;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

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;

public class AvgTemperature {

public static void main(String[] args) throws Exception{

//获取作业对象

Job job = Job.getInstance(new Configuration());

//设置主类

job.setJarByClass(AvgTemperature.class);

//设置job参数

job.setMapperClass(AvgTemperatureMapper.class);

job.setReducerClass(AvgTemperatureReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

//设置job输入输出

FileInputFormat.addInputPath(job, new Path("file:///simple/source.txt"));

FileOutputFormat.setOutputPath(job, new Path("file:///simple/output"));

     	System.exit(job.waitForCompletion(true) ? 0 : 1);

}

}

 

2.9 按照以上的步骤,把mapperreducer阶段以及测试代码编写完毕之后,选中测试类“AvgTemperature “,右键点击选择`Run as--->Java Application`,查看控制台显示内容查看是否正确执行。如图9所示


9

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mapreduce实验报告 前言和简介 MapReduce是Google提出的一种编程模型,在这个模型的支持下可以实现大规模并行化计 算。在Mapreduce框架下一个计算机群通过统一的任务调度将一个巨型任务分成许多部分 ,分别解决然后合并得到最终结果。Mapreduce可以让程序员以简单的程序来解决实际问 题,而隐藏了诸如分布、工作调度、容错、机器间通信,使得大规模任务简单而迅速地 完成。 1. Mapreduce的基本原理 1. 核心思想。 "Divide and Conquer"是Mapreduce的核心思想。面对一个规模庞大的问题,要 处理是以TB计的数据,Mapreduce采用"输入"------"分解"------"解决"----- -"聚合"------"输出结果"的基本过程。 2. 基本原理 Map和Reduce是两个核心操作,用户定义的map函数接收被切割过的原始的key/ value对集并且计算出一个中间key/value对集。Mapreduce库函数将所有的具有 相同key值的value聚合在一起交给用户定义的reduce函数处理。reduce函数将 同一key值的所有value合并成得到输出文件。在整个过程中,Mapreduce库函数 负责原始数据的切割,中间key/value对集的聚合,以及任务的调度,容错、通 信控制等基础工作。而用户定义的map和reduce函数则根据实际问题确定具体操 作。 2. 框架的基本结构和执行流程 基本结构 Mapreduce框架的主要程序分为三种即Master,Map和Reduce。 1. Master:主要功能有两个,任务的分割和任务的调度。Master把输入文件切成许 多个split,每个split文件一般为几十M。Master同时还要调度任务监视各个 map worker和reduce worker的工作状态,以做出相应的安排。Master还要监视各个子任务的完成进 展情况。 Master用到的数据结构 Struct Split[] //文件切割后的信息 struct MapSTATE[] //记录各个map任务的情况。 struct ReduceSTATE[R] //各个reduce任务的情况。 Type Map=0,Reduce=0 //记录map任务和reduce任务的完成个数。 MapWorkerSTATE[] ReduceWorkerSTATE[] //各个工作机器的忙闲状态 FileSplit(string inputfilename) //输入文件切割 JobAssign() //工作任务分配 2. Map:主要功能是读取经过切割split文件形成一个map任务,分析map任务,得到 中间结构并且将同一类型的中间文件存放在同一个区域内等待特定的reduce程 序读取。 3. Reduce:不同的Reduce读取各个Map得到的特定的中间文件,将所有相同的中间 文件整合成最后的输出文件。 任务执行基本流程 基本流程图见下一页 首先输入收据文件被Mapreduce库函数分割成M个split集。用户定义的程序被 拷贝到机群中,其中一个是master,其它的都是worker。M个map任务和R个reduc e任务将被分配。Master负责调度任务和过程监视。随时检测worker的工作状况, 任务的完成进度。Map worker每完成一个子任务向master报告。 一个被分配了map任务的worker读取一个split集,该worker从这个split集中 分析出key/value对,然后有map函数来处理这些key/value对并得到中间key/val ue对,这些key/value对将最终存放在map worker的本地硬盘上。每完成一个任务报告master。 中间key/value对被存在本地硬盘的R个不同的区域中,由于可能的key值很可 能不止R个,故必须利用一个分割函数来划分中间文件,常用的是散列的方法(如 hash(key) mod R)。保证key值相同的key/value对被存放同一区域中,并且将位置报告给maste r。如果同一个key的中间文件多而小可以考虑用cmobine函数在本地进行合并。 当所有的split都被分析完成之后,reduce worker开始工作,每个reduce根据master的安排和信息指示利用机群的内部文件 系统读取map worker本地磁盘中特定位置的中间文件。 Reduce开始聚合中间文件,得到自己的输出文件。在聚合的过程中由于有很 多key值,一般将用到排序。Reduce worker完成自己的工作后向master报告。 控制 分析key/value对 分区写入磁盘 读取 *单向箭头表示控制,双向箭头表示控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值