云计算(五)——Mapreduce 的使用

本文围绕MapReduce展开两个实验。一是计算整数的最大值和最小值,理解其执行原理、map和reduce阶段及函数使用;二是分析年气象数据平均温度,同样需理解相关原理与阶段,使用平均函数。详细介绍了实验环境、项目准备和程序编写步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Mapreduce 计算整数的最大值和最小值

【实验目的】

    1)理解mapreduce执行原理

    2)理解map,reduce阶段

    3)函数的使用

【实验原理】

    需求描述:

    对输入文件中数据进行计算找出这一组数据中的最大值和最小值。

    原始数据:

    102

    10

    39

    109

    200

    11

    3

    90

    28

    5

    2

    30

    838

    10005

    设计思路:

    Map处理的是一个纯文本文件,文件中存放的数据是一行一个数值。在执行map-reduce过程中按行进行读取数据。然后进行循环进行比较各个数值并最终找出这一系列数据中的最大值和最小值。Mapper处理的数据是由InputFormat分解过的数据集,其中 InputFormat的作用是将数据集切割成小数据集InputSplit,每一个InputSplit将由一个Mapper负责处理。此外,InputFormat中还提供了一个RecordReader的实现,并将一个InputSplit解析成<key,value>对提供给了map函数。InputFormat的默认值是TextInputFormat,它针对文本文件,按行将文本切割成InputSlit,并用 LineRecordReader将InputSplit解析成<key,value>对,key是行在文本中的位置,value是文件中的一行。Map的结果会通过partion分发到Reducer,Reducer做完Reduce操作后,将通过以格式OutputFormat输出。Mapper最终处理的结果对<key,value>,会送到Reducer中进行合并,合并的时候,有相同key的键/值对则送到同一个 Reducer上。Reducer是所有用户定制Reducer类地基础,它的输入是key和这个key对应的所有value的一个迭代器,同时还有 Reducer的上下文。Reduce的结果由Reducer.Context的write方法输出到文件中。

【实验环境】

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

    日志文件source.txt存放在/home/txtcode/目录下

【实验步骤】

    一、项目准备阶段

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

图1

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

图2

        1.3 本案例因为需要用到hadoop的计算,所以在编写程序之前需要先启动hadoop服务,可以在命令终端执行命令:start-all.sh 把hdfs和yarn服务启动。如图3所示

图3

    二、程序编写

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

图4

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

图5

        2.3 在编写“MaxMinMapper”类之前需要把hadoop相关的jar包导入,首先右击项目选择“New”—“Folder”创建一个lib文件夹并把指定位置中(桌面lib文件夹)的包放入该文件中。如图6所示

图6

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

图7

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

package com.simple.max.min.value;

import java.io.IOException;

import java.util.StringTokenizer;

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 MaxMinMapper  extends

                   Mapper<LongWritable, Text, Text, LongWritable>  {

         //为map设置一个固定的输出键

         private  final Text keyText = new Text("K");

         private  LongWritable val = new LongWritable(0);

         @Override

         protected  void map(LongWritable key, Text value, Context  context)

                            throws  IOException, InterruptedException  {

                   //为val对象设置读取的数值

                   val.set(Long.parseLong(value.toString()));

                   context.write(keyText, val);

         }

}

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

package com.simple.max.min.value;

import java.io.IOException;

 

import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Reducer;

public class MaxMinReducer  extends

Reducer<Text, LongWritable,  Text, Text> {

         //设置变量max和min的初始值

         private  long max=Long.MIN_VALUE;

         private  long min=Long.MAX_VALUE;

         @Override

         protected  void reduce(Text key, Iterable<LongWritable> values,Context  context)

                            throws  IOException, InterruptedException  {

                   //循环判断得出最大值和最小值

                   for(LongWritable val:values){

                            long  tmp = val.get();

                            if(tmp>max){

                                     max=tmp;

                            }

                            if(tmp<min){

                                     min=tmp;

                            }

                   }

                   //最大值和最小值分别输出

                   context.write(new Text("Max"),new  Text(max+"") );

                   context.write(new Text("Min"), new  Text(min+""));

         }

}

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

图8

 

        2.8 测试代码如下所示。

package com.simple.max.min.value;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.LongWritable;

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 MaxMinJob  {

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

                   //获取作业对象

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

                   //设置主类

                   job.setJarByClass(MaxMinJob.class);

                   //设置job参数

                   job.setMapperClass(MaxMinMapper.class);

                   job.setReducerClass(MaxMinReducer.class);

                   job.setMapOutputKeyClass(Text.class);

                   job.setMapOutputValueClass(LongWritable.class);

                  

                   job.setOutputKeyClass(Text.class);

                   job.setOutputValueClass(Text.class);

                   //设置job输入输出

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

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

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

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

         }

}

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

图9

        2.10 程序执行完毕之后,可以到输出信息目录/simple/output下,执行查看命令:cat part-r-00000查看对数据处理后产生的结果。如图10所示

 

 

 

二、Mapreduce 分析年气象数据平均温度

【实验目的】

    1)理解mapreduce执行原理

    2)理解map,reduce阶段

    3)平均函数的使用

【实验原理】

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

    气象采集数据格式如下:

    0067011990999991950051507004888888889999999N9+00001+9999999999999999999999

    0067011990999991950051512004888888889999999N9+00221+9999999999999999999999

    0067011990999991950051518004888888889999999N9-00111+9999999999999999999999

    0067011990999991949032412004888888889999999N9+01111+9999999999999999999999

    数据说明:

    第15-19个字符是year

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

    第50位值只能是0、1、4、5、9几个数字

【实验环境】

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

    日志文件source.txt存放在/home/txtcode/目录下

【实验步骤】

    一、项目准备阶段

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

图1

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

图2

        1.3 本案例因为需要用到hadoop的计算,所以在编写程序之前需要先启动hadoop服务,可以在命令终端执行命令:start-all.sh 把hdfs和yarn服务启动。如图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包导入,首先右击项目选择“New”—“Folder”创建一个lib文件夹并把指定位置中(桌面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 最后在项目src目录下指定的包名”com.simple.temperature”下右键点击,新建一个测试主类名为“AvgTemperature “添加测试代码如下所示。

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

图9

        2.10 程序执行完毕之后,可以到输出信息目录下,执行查看命令cat part-r-00000查看对采集数据处理后产生的结果。如图10所示

图10

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z2bns

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值