Hadoop日记Day15---MapReduce新旧api的比较
hadoop版本0.x的包一般是mapred
package old; import java.io.IOException;
import java.net.URI;
import java.util.Iterator; import mapreduce.WordCountApp; 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.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
/**
* hadoop版本1.x的包一般是mapreduce
* hadoop版本0.x的包一般是mapred
*
*/
public class OldAPP {
static final String INPUT_PATH = "hdfs://hadoop:9000/hello";
static final String OUT_PATH = "hdfs://hadoop:9000/out";
/**
* 改动:
* 1.不再使用Job,而是使用JobConf
* 2.类的包名不再使用mapreduce,而是使用mapred
* 3.不再使用job.waitForCompletion(true)提交作业,而是使用JobClient.runJob(job);
*
*/
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH);
if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
} final JobConf job = new JobConf(conf , WordCountApp.class);
//1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对
//job.setInputFormatClass(TextInputFormat.class); //1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
//map输出的<k,v>类型。如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略
//job.setMapOutputKeyClass(Text.class);
//job.setMapOutputValueClass(LongWritable.class); //1.3 分区
//job.setPartitionerClass(HashPartitioner.class);
//有一个reduce任务运行
//job.setNumReduceTasks(1); //1.4 TODO 排序、分组 //1.5 TODO 规约 //2.2 指定自定义reduce类
job.setReducerClass(MyReducer.class);
//指定reduce的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class); //2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
//指定输出文件的格式化类
//job.setOutputFormatClass(TextOutputFormat.class); //把job提交给JobTracker运行
JobClient.runJob(job);
} /**
* 新api:extends Mapper
* 老api:extends MapRedcueBase implements Mapper
*/
static class MyMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, LongWritable>{
@Override
public void map(LongWritable k1, Text v1,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
final String[] splited = v1.toString().split("\t");
for (String word : splited) {
collector.collect(new Text(word), new LongWritable(1));
}
}
} static class MyReducer extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable>{
@Override
public void reduce(Text k2, Iterator<LongWritable> v2s,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
long times = 0L;
while (v2s.hasNext()) {
final long temp = v2s.next().get();
times += temp;
}
collector.collect(k2, new LongWritable(times));
}
}
}
代码 1.1
一、自定义Mapper类的不同
在新api中,是继承类org.apache.hadoop.mapreduce.Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>。在旧api中,是继承类org.apache.hadoop.mapred.MapReduceBase,然后实现接口 org.apache.hadoop.mapred.Mapper<K1, V1, K2, V2>。在新api中,覆盖的map方法的第三个参数是Context类;在旧api中,覆盖的map方法的第三、四个形参分别是OutputCollector和Reporter类。在新api的Context中已经把两个类的功能合并到一起了,用户操作更简单。使用旧api的自定义Mapper类,如代码1.2所示所示。key、value对。每一个键值对调用一次map函数。
/**
* 新api:extends Mapper
* 老api:extends MapRedcueBase implements Mapper
*/
static class MyMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, LongWritable>{
@Override
public void map(LongWritable k1, Text v1,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
final String[] splited = v1.toString().split("\t");
for (String word : splited) {
collector.collect(new Text(word), new LongWritable(1));
}
}
}
代码 1.2
二、自定义Reducer类的不同
在新api中,是继承类org.apache.hadoop.mapreduce.Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>。在旧api中,是继承类org.apache.hadoop.mapred.MapReduceBase,然后实现接口 org.apache.hadoop.mapred. Reducer<K1, V1, K2, V2>。在新api中覆盖的reduce方法的第二个参数是java.lang.Iterable<VALUEIN>。在旧api中,覆盖的 reduce方法的第二个参数是java.util.Iterator<V 2>。前者可以使用增强for循环进行处理,后者只能使用 while循环处理了。在新api中,覆盖的reduce方法的第三个参数是Context类;在旧api中,覆盖的reduce方法的第三、四个形参分别是OutputCollector和Reporter类。在新api的Context中已经把两个类的功能合并到一起了,用户操作更简单。使用旧api的自定义Reducer类,代码如2.1所示。
static class MyReducer extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable>{
@Override
public void reduce(Text k2, Iterator<LongWritable> v2s,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
long times = 0L;
while (v2s.hasNext()) {
final long temp = v2s.next().get();
times += temp;
}
collector.collect(k2, new LongWritable(times));
}
}
代码 2.1
三、 驱动代码main方法的不同
在新api中,驱动代码主要是通过org.apache.hadoop.mapreduce.Job类实现的,通过该类管理各种配置,然后调用waitForCompleti on(boolean)方法把代码提交给JobTracker执行。在旧api中,驱动代码主要是通过 org.apache.hadoop.mapred.JobConf.JobConf(Con figuration, Class)类实现的,通过该类管理各种配置。对于job的提交,是通过org.apache.hadoop.mapred.JobClient类的 runJob(JobC onf)方法实现的。可见,新api中把JobConf和JobClient的功能进行了合并,用户调用更方便。
其中,JobConf类与Job类的方法名称几乎一致,只是传递的形参类型大不相同了。在新api中的Job类,要求setXXX(…)的形参必须是org .apache.hadoop.mapreduce及其子包下面的类;而旧api中的JobConf类,要求setXXX(…)的形参必须是 org.apache.hadoop.mapred及其子包下面的类。使用旧api的驱动代码main方法,如代码3.1所示。
package old; import java.io.IOException;
import java.net.URI;
import java.util.Iterator; import mapreduce.WordCountApp; 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.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.TextOutputFormat;
import org.apache.hadoop.mapred.lib.HashPartitioner;
/**
* hadoop版本1.x的包一般是mapreduce
* hadoop版本0.x的包一般是mapred
*
*/
public class OldAPP {
static final String INPUT_PATH = "hdfs://hadoop:9000/hello";
static final String OUT_PATH = "hdfs://hadoop:9000/out";
/**
* 改动:
* 1.不再使用Job,而是使用JobConf
* 2.类的包名不再使用mapreduce,而是使用mapred
* 3.不再使用job.waitForCompletion(true)提交作业,而是使用JobClient.runJob(job);
*
*/
public static void main(String[] args) throws Exception { Configuration conf = new Configuration();
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath = new Path(OUT_PATH);
if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
} final JobConf job = new JobConf(conf , WordCountApp.class); FileInputFormat.setInputPaths(job, INPUT_PATH);//1.1指定读取的文件位于哪里
job.setMapperClass(MyMapper.class);//1.2 指定自定义的map类
job.setMapOutputKeyClass(Text.class);//map输出的<k,v>类型。如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略
job.setMapOutputValueClass(LongWritable.class);
job.setPartitionerClass(HashPartitioner.class);//1.3 分区
job.setNumReduceTasks(1);//有一个reduce任务运行
job.setReducerClass(MyReducer.class);//2.2 指定自定义reduce类
job.setOutputKeyClass(Text.class);//指定reduce的输出类型
job.setOutputValueClass(LongWritable.class);
FileOutputFormat.setOutputPath(job, outPath);//2.3 指定写出到哪里
JobClient.runJob(job);//把job提交给JobTracker运行
} /**
* 新api:extends Mapper
* 老api:extends MapRedcueBase implements Mapper
*/
static class MyMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, LongWritable>{
@Override
public void map(LongWritable k1, Text v1,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
final String[] splited = v1.toString().split("\t");
for (String word : splited) {
collector.collect(new Text(word), new LongWritable(1));
}
}
} static class MyReducer extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable>{
@Override
public void reduce(Text k2, Iterator<LongWritable> v2s,
OutputCollector<Text, LongWritable> collector, Reporter reporter)
throws IOException {
long times = 0L;
while (v2s.hasNext()) {
final long temp = v2s.next().get();
times += temp;
}
collector.collect(k2, new LongWritable(times));
}
}
}
代码 3.1
Hadoop日记Day15---MapReduce新旧api的比较的更多相关文章
- mapreduce新旧api对比
对比:hadoop版本1.x 新版,hadoop版本0.x 旧版 1.新api引用包一般是mapreduce ,旧版api引用的包一般是mapred 2.新api使用Job,旧版api使用JobCon ...
- MapReduce简述、工作流程及新旧API对照
什么是MapReduce? 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查而且数出有多少张是黑桃. MapReduce方法则是: 1. 给在座的全部玩家中分配这摞牌. 2. 让每一个玩家数自己手 ...
- Hadoop2.2编程:新旧API的区别
Hadoop最新版本的MapReduce Release 0.20.0的API包括了一个全新的Mapreduce JAVA API,有时候也称为上下文对象. 新的API类型上不兼容以前的API,所以, ...
- MultipleOutputs新旧api
package MRNB_V4; import java.io.IOException; import java.util.Iterator; import org.apache.hadoop.con ...
- Hadoop日记系列目录
下面是Hadoop日记系列的目录,由于目前时间不是很充裕,以后的更新的速度会变慢,会按照一星期发布一期的原则进行,希望能和大家相互学习.交流. 目录安排 1> Hadoop日记Day1---H ...
- Hadoop MapReduce例子-新版API多表连接Join之模仿订单配货
文章为作者原创,未经许可,禁止转载. -Sun Yat-sen University 冯兴伟 一. 项目简介: 电子商务的发展以及电商平台的多样化,类似于京东和天猫这种拥有过亿用户的在线购 ...
- Hadoop生态圈-Kafka的新API实现生产者-消费者
Hadoop生态圈-Kafka的新API实现生产者-消费者 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Hadoop生态圈-Kafka的旧API实现生产者-消费者
Hadoop生态圈-Kafka的旧API实现生产者-消费者 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.旧API实现生产者-消费者 1>.开启kafka集群 [yinz ...
- hadoop下跑mapreduce程序报错
mapreduce真的是门学问,遇到的问题逼着我把它从MRv1摸索到MRv2,从年前就牵挂在心里,连过年回家的旅途上都是心情凝重,今天终于在eclipse控制台看到了job completed suc ...
随机推荐
- 【转】Linux---centos安装配置并挂载NFS
转自:http://blog.csdn.net/loyachen/article/details/51010688 [系统环境] CentOS release 6.7 (Final) 服务端配置 1. ...
- 【three.js练习程序】动画效果,100个方块随机运动
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- LeetCode题解之Merge Two Sorted Lists
1.题目描述 2.题目分析 题目要求合并有序的两个链表,要求不能额外申请空间. 3.代码 ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { i ...
- eclipse中svn插件的工程不能与svn资源库同步的解决方法
eclipse中svn插件的工程不能与svn资源库同步的解决办法 最近几天自己的工程与资源库同步总是出现问题,重启机器后发现资源库丢失了,无法进行同步. 解决办法如下: 1.右键工程---->选 ...
- mysql 内存统计
在 mysql 5.5 中实现了类似mysql5.7中performance schema 的内存统计功能. 功能 1 展示mysql层内存总大小. 2 展示mysql层内存使用分布情况. 3 展示每 ...
- python的类基础
python类的基础: 1,面向对象的基本概念 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的 ...
- 使用postman给servlet传各种参数
web开发中经常会使用到postman软件,常用的方法涉及到get和post方法去获取对应json数据,get方法直接传url就可以,返回对应json数据.但是post请求就需要json数据提交,而且 ...
- 破解 jar 包之直接修改 .class 文件方式
一.常规 JAVA 软件破解流程 先讲一下常规jar包的破解流程. 1. 快速定位. 1) 通过procmon监控相关软件,查看程序都访问了些啥. 2) 用jd-gu ...
- Hsqldb中设置主键,并让主键自增
CREATE TABLE userinfo ( Id INTEGER GENERATED BY DEFAULT AS IDENTITY, Name varchar(100) NOT NULL, Dep ...
- [BZOJ 1135][POI2009]Lyz
[BZOJ 1135][POI2009]Lyz 题意 初始时滑冰俱乐部有 \(1\) 到 \(n\) 号的溜冰鞋各 \(k\) 双.已知 \(x\) 号脚的人可以穿 \(x\) 到 \(x+d\) 的 ...