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 ...
随机推荐
- Expo大作战(四)--快速用expo构建一个app,expo中的关键术语
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- 迁移MSSQL实例的所有login(包含密码)
迁移数据库的时候肯定会涉及到login的迁移(包含数据库除外). 而一般我们迁移login的时候,可能会使用在某个login上右键生成脚本这样的做法.但是这样生成的脚本不能把密码也生成出来. 而且你只 ...
- MSSQL段落还原脚本
--段落还原:数据库损坏范围比较大,跨多个数据文件甚至跨文件组的时候,我们不得不恢复整个数据库.--这时如果数据库特别大,数据库恢复时间将会很长.但我们可以使用SQL Server提供的段落还原,来逐 ...
- linux内核完全剖析——基于0.12内核-笔记(2)-统一编址和独立编址
IO是什么 ? IO(Input and Output)是输入输出接口.是CPU和其他外部设备(如串口.LCD.触摸屏.LED等)之间通信的接口.一般的,我们说的IO就是指CPU的各种内部或外部外设. ...
- env :让系统决定你命令的位置
如果我们使用lua 运行脚本程序,或者使用python执行程序.我们不用明确 python的位置,可以使用env 命令来运行: env 程序介绍: NAME env - run a program i ...
- python基础学习16----模块
模块(Module)的引入 import 模块名 调用模块中的函数的方式为 模块名.函数名 这种方式引入会相当于将模块中代码执行一遍,所以如果引入的模块中有输出语句,那么只写import 模块名,运行 ...
- 使用Index()+Match()函数实现更为灵活的VLookUp()
上一篇 http://www.cnblogs.com/-SANG/p/8407017.html 文章中已经介绍了vlookup的用法. 今天要使用index+match实现更为灵活的vlookup 先 ...
- 开源作业调度框架 - Quartz.NET - Cron表达式测试
昨天简单写了一下如何使用Quzrtz.NET. 那么问题来了,我设置了Cron表达式之后如何知道是表达式是否按照预期的时间执行了呢? 我找到了些Cron表达式工具生成了表达式,确发现它们基本上没有进行 ...
- November 11th, 2017 Week 45th Saturday
Happiness is a direction, not a place. 快乐是一个方向,不是一个目的. Do you remember those moments in your life wh ...
- vultr vps(ubuntu)忘记密码
参考官方解决方案:https://www.vultr.com/docs/boot-into-single-user-mode-reset-root-password 在此仅给出ubuntu下的解决 D ...