Java 实现MapReduce函数
明白了MapReduce程序的工作原理之后,下一步就是写代码来实现它。我们需要三样东西:一个map函数、一个reduce函数和一些用来运行作业的代码。map函数由Mapper类来表示,后者声明一个map()虚方法。范例2-3显示了我们的map函数实现。
范例2-3 查找最高气温的Mapper类
Import java.Io.IOException;
import org.apahce.hadoop.io.IntWritable;
import org.apahce.hadoop.io.LongWritable;
import org.apahce.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class MaxTemperatureMapper extends MapReduceBase implements Mapper<LongWritable,Text,Text,IntWritable>{ private static final int MISSING = 9999; @Override
public void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException{
String line = value.toString();
String year = line.substring(15,19);
int airTemperature; if(line.charAt(87) =='+'){
airTemperature = Integer.parseInt(line.substring(88,92));
else{
airTemperature = Integer.parseInt(line.subtring(87,92));
}
String quality = line.substring(92,93);
if(airTemperature != MISSING &&quality.matches("[01459]")){
context.write(new Text(year),new IntWritetable(airTemperature));
} } } }
这个Mapper类是一个泛型类型,他有四个行参类型,分别指定:map函数的输入键,输入值,输出键和输出值的类型。就现在的例子来说,输入键是一个长整数偏移量,输入值是一行文本,输出键是年份,输出值是气温(整数)。Hadoop本身提供了一套可优化网络序列化传输的基本类型,而不直接使用Java内嵌的类型。这些类型都在org.apache.hadoop.io包中。这里使用LongWritable类型(相当于Java的Long类型)、Text类型(相当于Java的String类型)和IntWritable类型(相当于Java的Integer类型)。
map()方法的输入时一个键和一个值。我们首先将包含有一行输入的Text值转换成Java的String类型,之后使用substring()方法提取我们感兴趣的列。
map()方法还提供了Context实例用于输出内容的写入。在这种情况下,我们将年份按Text对象进行读/写(因为我们把年份当作键),将气温值封装在IntWritable类型中。只有气温数据不缺并且对应质量代码显示为正确的气温读数时,这些数据才会被写入输出记录中。
以类似方法用Reducer来定义reduce函数,如范例2-4所示。
范例2-4.查找最高气温的Reducer类
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apche.hadoop.io.Text;
import org.apche.hadoop.mapreduce.Reducer; public class MaxTemperatureReducer extends Reducer<Text,IntWritable,Text,IntWritable>{ @Overide public void reduce(Text key,Interable<IntWritable> values,Context context){
int maxValue = Integer.MIN_VALUE;
for(IntWritable value:values){
maxValue = Max.max(maxValue,value.get());
}
context.write(key,new IntWritable(maxValue)); } }
同样,reduce函数也有四个形式参数类型用于指定输入和输出类型。reduce函数的输入类型必须匹配map函数的输出类型:即Text类型和IntWritable类型。在这种情况下,reduce函数的输出类型也必须是Text和IntWritable类型,分别输出年份及其最高气温。这个最高气温是通过循环比较每个气温与当前所知最高气温所得到的。
第三部分代码负责运行MapReduce作业(请参见范例2-5)
范例2-5 这个应用程序在气象数据集中找出最高气温
import java.oo.IOException;
import org.apache.hadoop.fs.Path;
import org.apahce.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.input.FileOutputFormat;
import org.apache.hadoop.mapreduce.input.FileOutputFormat; public class MaxTemperature{ public static void main(String[] args) throws Exception{ if(args.length !=2){
System.err.printlin("Usage:MaxTemperature<input path> <output path>");
System.exit(-1); } Job job = new Job();
job.serJarByClass(MaxTemperature.class);
job.setName("Max temperature"); FileInputFormat.addInputPath(job,new Path(args[0]));
FileOutputFormat.setOutputPath(job,new Path([args[1])); job.setMapperClass(MaxTemperatureMapper,class);
job.setReducerClass(MaxTemperatureReducer.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); System.exit(job.waitForCompletion(true)?0:1); } }
Job对象可以指定作业执行规范。我们可以用它来控制整个作业的运行。我们在Hadoop集群上运行这个作业时,要把代码打包成一个Jar文件(Haoop在集群上发布在合格文件)。
不必明确指定JAR文件的名称,在Job对象的setJarByClass()方法中传递一个类即可,Hadoop利用这个类来查找包含它的JAR文件,进而找到相关的Jar文件。
构造Job对象之后,需要指定输入和输出数据的路径。调用FileInputFormat类的静态方法addInputPath()来定义输入数据的路径,这个路径可以是单个的文件、一个目录(此时,将目录下所有文件当做输入)或符合特定文件模式的一系列文件。由函数名可知,可以多次调用addInputPath()来实现多路径的输入。
调用FileOutputFormat类中的静态方法setOutputPath()来指定输出路径(只能有一个输出路径)。这个方法指定的是reduce函数输出文件的写入目录。在运行作业前该目录是不应该存在的,否则Hadoop会报错并拒绝运行作业。这种预防措施的目的是放置数据丢失(长时间运行的作业如果结果被意外覆盖,肯定是非常恼人的)。
接着,调用setMapperClas()和setReducerClass()指定map类型和reduce类型。
setOutputKeyClass()和setOutputValueClass()控制map和reduce函数的输出类型,正如本例所示,这两个输出类型一般都是相同的。如果不同,则通过setMapOutputKeyClass()和setMapOutputValueClass()来设置mao函数的输出类型。
输入的类型通过InputFormat类来控制,我们的例子中没有设置,因为使用的是默认的TextInputFormat(文本输入格式)。
在设置定义map和reduce函数的类之后,可以开始运行作业。Job中的waitForCompletion()方法提交作业并等待执行完成。该方法中的布尔参数是个详细标识,所以作业会把进度写到控制台。
waitForCompletion()方法返回一个布尔值,表示执行的成(true)败(false)。
Java 实现MapReduce函数的更多相关文章
- 简单的java Hadoop MapReduce程序(计算平均成绩)从打包到提交及运行
[TOC] 简单的java Hadoop MapReduce程序(计算平均成绩)从打包到提交及运行 程序源码 import java.io.IOException; import java.util. ...
- java String.split()函数的用法分析
java String.split()函数的用法分析 栏目:Java基础 作者:admin 日期:2015-04-06 评论:0 点击: 3,195 次 在java.lang包中有String.spl ...
- Android使用JNI(从java调用本地函数)
当编写一个混合有本地C代码和Java的应用程序时,需要使用Java本地接口(JNI)作为连接桥梁.JNI作为一个软件层和API,允许使用本地代码调用Java对象的方法,同时也允许在Java方法中调用本 ...
- 关于C++与Java中虚函数问题的读书笔记
之前一直用C++编程,对虚函数还是一些较为肤浅的理解.可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题. Java中的虚函数 以下是段别人的 ...
- 用JAVA写一个函数,功能例如以下: 随意给定一组数, 找出随意数相加之后的结果为35(随意设定)的情况
用JAVA写一个函数.功能例如以下:随意给定一组数,比如{12,60,-8,99,15,35,17,18},找出随意数相加之后的结果为35(随意设定)的情况. 能够递归算法来解: package te ...
- java中main函数解析(转载)
从写java至今,写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己,为什么要这么写,因为在c语言中就没有这样子的要 ...
- java的数学函数总结
java的数学函数都放在java.lang这个包中,并且这些函数的方法在类Math中是作为static方法出现的,所以要引用一个特定的函数,只需将类Math和一个圆点写在要使用的方法前就好.如方法sq ...
- JAVA中字符串函数subString的用法小结
本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...
- Java中的函数对象
初次听说java中的函数对象可能,比较的陌生.可以类比着来理解一下,人们常说java中没有了指针,殊不知,java中的对象引用就是指针,有时候我们说一个对象往往指的就是这个对象的引用,也就是说基本上把 ...
随机推荐
- HDU5863 cjj's string game(DP + 矩阵快速幂)
题目 Source http://acm.split.hdu.edu.cn/showproblem.php?pid=5863 Description cjj has k kinds of charac ...
- java实现文件上传--flash上传
1.http请求的头信息是“application/octet-stream”,request body 是二进制的flash图片流 2.把流中的信息读入到文件中 代码如下,代码分三个部分: ---- ...
- ReSharper 配置及用法(二)
下载工具 一:Reshaper是什么 即便是那些整天攻击 .NET 和 C# 的人,也常常不得不承认 Visual Studio 确实是个够强大的 IDE,除非他认为更少的 IDE 功能和命令行调试才 ...
- soapui中文操作手册(三)----使用SoapUI进行负载测试
使用了SoapUI进行负载测试 负载测试是相当独特的,我们已经创建了一个功能,使您能够快速创建性能测试,并很容易地修改它们.SoapUI性能测试通常是从现有功能测试创建.这使您可以非常快速地创建先进的 ...
- [R语言]foreach和doParallel包实现多个数据库同时查询
R语言在进行数据库查询时,每执行一条语句,都会阻塞.直到查询语句返回结果之后,才会进行下一条语句. 为了能够实现同时对多个数据库进行查询,以节省顺序执行下来的时间,首先考虑通过多线程来进行数据库查询. ...
- Android MultiDex
出现的原因: 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt.DexOpt的执行过程是在第一次加载Dex文件的时候执行的.这个过程会生 ...
- Android 应用内存优化 之 onLowMemory & onTrimMemory
OnLowMemory: 是Android提供的API,在系统内存不足,所有后台程序(优先级为background的进程,不是指后台运行的进程)都被杀死时,系统会调用OnLowMemory.OnTri ...
- Codeforces Round #242 (Div. 2) C. Magic Formulas
解题思路是: Q=q1^q2.......^qn = p1^p2......^pn^((1%1)^....(1%n))^((2%1)^......(2%n))^.... 故Q的求解过程分成两部分 第一 ...
- BZOJ 1015 题解
1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...
- 【BZOJ】1975: [Sdoi2010]魔法猪学院
题意 \(n(2 \le n \le 5000)\)个点,找尽量多的不同\(1\)到\(n\)的路径,每一次的花费就是路径的全值和,要求在费用不超过\(E\)的情况下路径最多. 分析 裸的最段路. 题 ...