MapReduce工作流多种实现方式
学习 hadoop,必不可少的就是编写 MapReduce 程序。当然,对于简单的分析程序,我们只需一个 MapReduce 任务就能搞定,然而对于比较复杂的分析程序,我们可能需要多个Job或者多个Map或者Reduce进行分析计算。 本课程我们主要学习多个 Job 或者多个 MapReduce 的编程形式。
MapReduce 的主要有以下几种编程形式。
迭代式 MapReduce
MapReduce 迭代方式,通常是将上一个 MapReduce 任务的输出作为下一个 MapReduce 任务的输入,可只保留 MapReduce 任务的最终结果,中间数据可以删除或保留,可根据业务需要自行决定。 迭代式 MapReduce 的示例代码如下所示。
Configuration conf = new Configuration(); //第一个 MapReduce 任务
Job job1 = new Job(conf,"job1");
.....
FileInputFormat.addInputPath(job1,input);//job1的输入
FileOutputFromat.setOutputPath(job1,out1);//job1的输出
job1.waitForCompletion(true); //第二个 Mapreduce 任务
Job job2 = new Job(conf,"job2");
.....
FileInputFormat.addInputPath(job2,out1);//job1的输出作为job2的输入
FileOutputFromat.setOutputPath(job2,out2);//job2 的输出
job2.waitForCompletion(true); //第三个 Mapreduce 任务
Job job3 = new Job(conf,"job3");
.....
FileInputFormat.addInputPath(job3,out2);//job2的输出作为job3的输入
FileOutputFromat.setOutputPath(job3,out3);//job3 的输出
job3.waitForCompletion(true);
.....
虽然 MapReduce 的迭代可实现多任务的执行,但是它具有如下两个缺点:
1、每次迭代,如果所有 Job 对象重复创建,代价将非常高。
2、每次迭代,数据都要写入本地,然后从本地读取,I/O和网络传输的代价比较大。
依赖关系式 MapReuce
依赖关系式 MapReduce主要是由 org.apache.hadoop.mapred.jobcontrol 包中的 JobControl 类来实现。JobControl 的实例表示一个作业的运行图, 你可以加入作业配置,然后告知 JobControl 实例作业之间的依赖关系。在一个线程中运行 JobControl 时,它将按照依赖顺序来执行这些作业。也可以查看进程, 在作业结束后,可以查询作业的所有状态和每个失败相关的错误信息。如果一个作业失败,JobControl 将不执行与之有依赖关系的后续作业。
依赖关系式 MapReuce 的示例代码如下所示。
Configuration conf1 = new Configuration();
Job job1 = new Job(conf1,"Job1");
.........//job1 其它设置 Configuration conf2 = new Configuration();
Job job2 = new Job(conf2,"Job2");
.........//job2 其它设置 Configuration conf3 = new Configuration();
Job job3 = new Job(conf3,"Job3");
.........//job3 其它设置 ControlledJob cJob1 = new ControlledJob(conf1);//构造一个 Job
cJob1.setJob(job1);//设置 MapReduce job
ControlledJob cJob2 = new ControlledJob(conf2);
cJob2.setJob(job2);
ControlledJob cJob3 = new ControlledJob(conf3);
cJob3.setJob(job3); cJob3.addDependingJob(cJob1);//设置job3和job1的依赖关系
cJob3.addDependingJob(cJob2);//设置job3和job2的依赖关系 JobControl JC = new JobControl("123");
//把三个构造的job加入到JobControl中
JC.addJob(cJob1);
JC.addJob(cJob2);
JC.addJob(cJob3);
Thread t = new Thread(JC);
t.start();
while (true) {
if (jobControl.allFinished()) {
jobControl.stop();
break;
}
}
注意:hadoop的JobControl类实现了线程Runnable接口。我们需要实例化一个线程来启动它。直接调用JobControl的run()方法,线程将无法结束。
线性链式 MapReduce
大量的数据处理任务涉及对记录的预处理和后处理。
例如:在处理信息检索的文档时,可能一步是移除 stop words(像a、the和is这样经常出现但不太有意义的词),另一步做stemming(转换一个词的不同形式为相同的形式,例如转换finishing和finished为finish)。
你可以为预处理与后处理步骤各自编写一个 MapReduce 作业,并把它们链接起来。在这些步骤中可以使用IdentityReducer(或完全不同的 Reducer)。 由于过程中每一个步骤的中间结果都需要占用I/O和存储资源,这种做法是低效的。另一种方法是自己写 mapper去预先调用所有的预处理步骤,再让reducer调用所有的后处理步骤。这将强制你采用模块化和可组合的方式来构建预处理和后处理。因此Hadoop引入了ChainMapper 和ChainReducer类来简化预处理和后处理的构成。
hadoop提供了专门的链式ChainMapper和ChainReducer来处理线性链式MapReduce任务。在Map或者Reduce阶段存在多个Mapper,这些Mapper像Linux管道一样,前一个Mapper的输出结果直接重定向到后一个Mapper的输入,形成流水线。 其调用形式如下:
... //预处理
ChainMapper.addMapper(...);
ChainReducer.setReducer(...);
ChainReducer.addMapper(...);
... //后处理
//addMapper()调用的方法形式如下:
public static void addMapper(Job job,
Class< extends Mapper> mclass,
Class< extends K1> inputKeyClass,
Class< extends V1> inputValueClass,
Class< extends K2> outputKeyClass,
Class< extends V2> outputValueClass,
Configuration conf
)
addMapper()方法有8个参数。第一个和最后一个分别为全局的Job和本地的configuration对象。第二个参数是 Mapper类,负责数据处理。余下4个参数 inputKeyClass、inputValueClass、outputKeyClass和outputValueClass是这个Mapper类中输入/输出类的类型。ChainReducer专门提供了一个setReducer()方法来设置整个作业唯一的Reducer,语法与addMapper()方法类似。
线性链式 MapReduce 的示例代码如下所示。
public void function throws IOException {
Configuration conf = new Configuration();
Job job = new Job(conf);
job.setJobName("chainjob");
job.setInputFormat(TextInputFormat.class);
job.setOutputFormat(TextOutputFormat.class);
FileInputFormat.addInputPath(job, in);
FileOutputFormat.setOutputPath(job, out);
//在作业中添加 Map1 阶段
Configuration map1conf = new Configuration(false);
ChainMapper.addMapper(job, Map1.class, LongWritable.class, Text.class,Text.class, Text.class, true, map1conf);
//在作业中添加 Map2 阶段
Configuration map2conf = new Configuration(false);
ChainMapper.addMapper(job, Map2.class, Text.class, Text.class,LongWritable.class, Text.class, true, map2conf);
//在作业中添加 Reduce 阶段
Configuration reduceconf = new Configuration(false);
ChainReducer.setReducer(job,Reduce.class,LongWritable.class,Text.class,Text.class,Text.class,true,reduceconf);
//在作业中添加 Map3 阶段
Configuration map3conf = new Configuration(false);
ChainReducer.addMapper(job,Map3.class,Text.class,Text.class,LongWritable.class,Text.class,true,map3conf);
//在作业中添加 Map4 阶段
Configuration map4conf = new Configuration(false);
ChainReducer.addMapper(job,Map4.class,LongWritable.class,Text.class,LongWritable.class,Text.class,true,map4conf);
job.waitForCompletion(true);
}
注意:对于任意一个MapReduce作业,Map和Reduce阶段可以有无限个Mapper,但是Reduce只能有一个。所以包含多个Reduce的作业,不能使用 ChainMapper/ChainReduce来完成。
MapReduce工作流多种实现方式的更多相关文章
- Spark源码分析:多种部署方式之间的区别与联系(转)
原文链接:Spark源码分析:多种部署方式之间的区别与联系(1) 从官方的文档我们可以知道,Spark的部署方式有很多种:local.Standalone.Mesos.YARN.....不同部署方式的 ...
- C#高性能TCP服务的多种实现方式
哎~~ 想想大部分园友应该对 "高性能" 字样更感兴趣,为了吸引眼球所以标题中一定要突出,其实我更喜欢的标题是<猴赛雷,C#编写TCP服务的花样姿势!>. 本篇文章的主 ...
- C#开发微信门户及应用(11)--微信菜单的多种表现方式介绍
在前面一系列文章中,我们可以看到微信自定义菜单的重要性,可以说微信公众号账号中,菜单是用户的第一印象,我们要规划好这些菜单的内容,布局等信息.根据微信菜单的定义,我们可以看到,一般菜单主要分为两种,一 ...
- 顺序表及其多种实现方式 --- C/C++
所谓顺序表,即线性表的顺序存储结构.下面给出的是数据结构---线性表的定义. ADT List{ 数据对象: 线性表的数据对象的集合为{a1,a2,a3,...,an},每个元素的类型为ElemTyp ...
- Android开发中怎样调用系统Email发送邮件(多种调用方式)
在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外,所谓的调用Email,只是说Email可以接收Intent并做这些事情 我们都知道,在Android中 ...
- Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护
Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护 数据加密又称password学,它是一门历史悠久的技术,指通过加密算法和加密密钥将明文转变为密文.而解密则是通过解密 ...
- spring 文件模板下载多种实现方式
针对于文件的下载,我们有很多种实现方式.业务场景是这样子的,要实现Excel文件的导入和导出功能,问题对于java的POI操作没有问题,所以实现文件的下载就相对简单,只需要从数据库取出相关的数据,针对 ...
- C# 高性能 TCP 服务的多种实现方式
哎~~ 想想大部分园友应该对 "高性能" 字样更感兴趣,为了吸引眼球所以标题中一定要突出,其实我更喜欢的标题是<猴赛雷,C# 编写 TCP 服务的花样姿势!>. 本篇文 ...
- SVN服务的模式和多种访问方式 多种访问原理图解与优缺点
SVN企业应用场景 SVN任是当前企业的主流.git正在发展,未来会成为主流.如果大家精力足够,建议同时掌握. 1.4运维人员掌握版本管理 对于版本管理系统,运维人员需要掌握的技术点: 1.安装.部署 ...
随机推荐
- ASP.NET Web API Selfhost宿主环境中管道、路由
ASP.NET Web API Selfhost宿主环境中管道.路由 前言 前面的几个篇幅对Web API中的路由和管道进行了简单的介绍并没有详细的去说明一些什么,然而ASP.NET Web API这 ...
- C# 开发windows服务的一些心得
最近在做一个windows服务的项目,发现并解决了一些问题,拿出来和大家分享一下,以下windows服务简称“服务” 文章会在适合时间更新,因为朋友们在不断提出新的意见或思路,感谢-.- 1.服务如何 ...
- PHP Excel 下载数据,并分页下载
直接上代码: 调用下载Excel: $total=$duoduo->count(MOD.' as a',$where); $objExcel= SelfExcelObject(); //导出 i ...
- ActiveMQ的集群方案对比及部署
转载:http://blog.csdn.net/lifetragedy/article/details/51869032 ActiveMQ的集群 内嵌代理所引发的问题: 消息过载 管理混乱 如何解决这 ...
- JavaScript中的apply,call与this的纠缠
1.apply定义 apply:调用函数,并用指定对象替换函数的 this 值,同时用指定数组替换函数的参数. 语法:apply([thisObj[,argArray]]) thisObj 可选.要用 ...
- HTML5 学习总结(三)——本地存储
一.HTML4客户端存储 B/S架构的应用大量的信息存储在服务器端,客户端通过请求响应的方式从服务器获得数据,这样集中存储也会给服务器带来相应的压力,有些数据可以直接存储在客户端,传统的Web技术中会 ...
- Oracle 11g DG配置简明版
环境: 主库A机:在线生产环境,RHEL 6.4 + Oracle 11.2.0.3 备库B机:新增备机,RHEL 6.4 需求: 对生产环境最小影响前提下配置DG备库. 目录: 一.B机安装相同版本 ...
- PHP环境配置
PHP环境配置 1.Apache的安装 第一步: 1. 双击httpd-2.2.17-win32-x86-no_ssl.msi.出现 Windows 标准的软件安装欢迎界面,直接点“Next”继 ...
- C#组件系列———又一款日志组件:Elmah的学习和分享
前言:好久没动笔了,都有点生疏,12月都要接近尾声,可是这月连一篇的产出都没有,不能坏了“规矩”,今天还是来写一篇.最近个把月确实很忙,不过每天早上还是会抽空来园子里逛逛.一如既往,园子里每年这个时候 ...
- Javascript本地存储小结
前言 总括:详细讲述Cookie,LocalStorge,SesstionStorge的区别和用法. 人生如画,岁月如歌. 原文博客地址:Javascript本地存储小结 知乎专栏&& ...