如何在Hadoop上编写MapReduce程序
1. 概述
1970年,IBM的研究员E.F.Codd博士在刊物《Communication of the ACM》上发表了一篇名为“A Relational Model of Data for Large Shared Data Banks”的论文,提出了关系模型的概念,标志着关系数据库的诞生,随后几十年,关系数据库及其结构化查询语言SQL成为程序员必须掌握的基本技能之一。
2005年4月,Jeffrey Dean和Sanjay Ghemawat在国际会议OSDI上发表“MapReduce: Simplified Data Processing on Large Cluster”,标志着google的大规模数据处理系统MapReduce公开。受这篇论文的启发,当年秋天,Hadoop 由 Apache Software Foundation 公司作为 Lucene 的子项目 Nutch 的一部分正式被引入,2006 年 3 月份,MapReduce 和 Nutch Distributed File System (NDFS) 分别被纳入称为 Hadoop 的项目中。如今,Hadoop已经被超过50%的互联网公司使用,其他很多公司正准备使用Hadoop来处理海量数据,随着Hadoop越来越受欢迎,也许在将来的某段时间,Hadoop会成为程序员必须掌握的技能之一,如果真是这样的话,学会如何在Hadoop上编写MapReduce程序便是学习Hadoop的开始。
本文介绍了在Hadoop上编写MapReduce程序的基本方法,包括MapReduce程序的构成,不同语言开发MapReduce的方法等。
2. Hadoop 作业构成
2.1 Hadoop作业执行流程
用户配置并将一个Hadoop作业提到Hadoop框架中,Hadoop框架会把这个作业分解成一系列map tasks 和reduce tasks。Hadoop框架负责task分发和执行,结果收集和作业进度监控。
下图给出了一个作业从开始执行到结束所经历的阶段和每个阶段被谁控制(用户 or Hadoop框架)。
下图详细给出了用户编写MapRedue作业时需要进行那些工作以及Hadoop框架自动完成的工作:
在编写MapReduce程序时,用户分别通过InputFormat和OutputFormat指定输入和输出格式,并定义Mapper和Reducer指定map阶段和reduce阶段的要做的工作。在Mapper或者Reducer中,用户只需指定一对key/value的处理逻辑,Hadoop框架会自动顺序迭代解析所有key/value,并将每对key/value交给Mapper或者Reducer处理。表面上看来,Hadoop限定数据格式必须为key/value形式,过于简单,很难解决复杂问题,实际上,可以通过组合的方法使key或者value(比如在key或者value中保存多个字段,每个字段用分隔符分开,或者value是个序列化后的对象,在Mapper中使用时,将其反序列化等)保存多重信息,以解决输入格式较复杂的应用。
2.2 用户的工作
用户编写MapReduce需要实现的类或者方法有:
(1) InputFormat接口
用户需要实现该接口以指定输入文件的内容格式。该接口有两个方法
1
2
3
4
5
6
7
8
9
10
11
|
public interface InputFormat<K, V> {
InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;
RecordReader<K, V> getRecordReader(InputSplit split,
JobConf job,
Reporter reporter) throws IOException;
}
|
其中getSplits函数将所有输入数据分成numSplits个split,每个split交给一个map task处理。getRecordReader函数提供一个用户解析split的迭代器对象,它将split中的每个record解析成key/value对。
Hadoop本身提供了一些InputFormat:
(2)Mapper接口
用户需继承Mapper接口实现自己的Mapper,Mapper中必须实现的函数是
1
2
3
4
5
6
7
8
9
|
void map(K1 key,
V1 value,
OutputCollector<K2,V2> output,
Reporter reporter
) throws IOException
|
其中,<K1 V1>是通过Inputformat中的RecordReader对象解析处理 的,OutputCollector获取map()的输出结果,Reporter保存了当前task处理进度。
Hadoop本身提供了一些Mapper供用户使用:
(3)Partitioner接口
用户需继承该接口实现自己的Partitioner以指定map task产生的key/value对交给哪个reduce task处理,好的Partitioner能让每个reduce task处理的数据相近,从而达到负载均衡。Partitioner中需实现的函数是
getPartition( K2 key, V2 value, int numPartitions)
该函数返回<K2 V2>对应的reduce task ID。
用户如果不提供Partitioner,Hadoop会使用默认的(实际上是个hash函数)。
(4)Combiner
Combiner使得map task与reduce task之间的数据传输量大大减小,可明显提高性能。大多数情况下,Combiner与Reducer相同。
(5)Reducer接口
用户需继承Reducer接口实现自己的Reducer,Reducer中必须实现的函数是
1
2
3
4
5
6
7
8
9
|
void reduce(K2 key,
Iterator<V2> values,
OutputCollector<K3,V3> output,
Reporter reporter
) throws IOException
|
Hadoop本身提供了一些Reducer供用户使用:
(6)OutputFormat
用户通过OutputFormat指定输出文件的内容格式,不过它没有split。每个reduce task将其数据写入自己的文件,文件名为part-nnnnn,其中nnnnn为reduce task的ID。
Hadoop本身提供了几个OutputFormat:
3. 分布式缓存
Haoop中自带了一个分布式缓存,即DistributedCache对象,方便map task之间或者reduce task之间共享一些信息,比如某些实际应用中,所有map task要读取同一个配置文件或者字典,则可将该配置文件或者字典放到分布式缓存中。
4. 多语言编写MapReduce作业
Hadoop采用java编写,因而Hadoop天生支持java语言编写作业,但在实际应用中,有时候,因要用到非java的第三方库或者其他原因,要采用C/C++或者其他语言编写MapReduce作业,这时候可能要用到Hadoop提供的一些工具。
如果你要用C/C++编写MpaReduce作业,可使用的工具有Hadoop Streaming或者Hadoop Pipes。
如果你要用Python编写MapReduce作业,可以使用Hadoop Streaming或者Pydoop。
如果你要使用其他语言,如shell,php,ruby等,可使用Hadoop Streaming。
关于Hadoop Streaming编程,可参见我的这篇博文:《Hadoop Streaming编程》(http://dongxicheng.org/mapreduce/hadoop-streaming-programming/ )
关于Pydoop编程,可参见其官方网站:http://sourceforge.net/projects/pydoop/
关于Hadoop pipes编程,可参见《Hadoop Tutorial 2.2 — Running C++ Programs on Hadoop》。
5. 编程方式比较
(1)java。 Hadoop支持的最好最全面的语言,而且提供了很多工具方便程序员开发。
(2)Hadoop Streaming。 它最大的优点是支持多种语言,但效率较低,reduce task需等到map 阶段完成后才能启动;它不支持用户自定义InputFormat,如果用户想指定输入文件格式,可使用java语言编写或者在命令行中指定分隔符;它采用标准输入输出让C/C++与java通信,因而只支持text数据格式。
(3)Hadoop Pipes。 专门为C/C++语言设计,由于其采用了socket方式让C/C++与java通信,因而其效率较低(其优势在于,但作业需要大量,速度很快)。它支持用户(用C/C++)编写RecordReader。
(4)Pydoop。它是专门方便python程序员编写MapReduce作业设计的,其底层使用了Hadoop Streaming接口和libhdfs库。
6. 总结
Hadoop使得分布式程序的编写变得异常简单,很多情况下,用户只需写map()和reduce()两个函数即可(InputFormat,Outputformat可用系统缺省的)。正是由于Hadoop编程的简单性,越来越多的公司或者研究单位开始使用Hadoop。
7. 注意事项
(1) Hadoop默认的InputFormat是TextInputFormat,它将文件中的每一行作为value,该行的偏移量为key。
(2)如果你的输入是文本文件,且每一行包括key,value,则可使用Hadoop中自带的KeyValueTextInputFormat,它默认的每行是一个key/value对,且key与value的分割如为TAB(’\t‘),如果想修改key/value之间的分隔符,如将分割符改为“,”,可使用conf.set(“key.value.separator.in.input.line”,”,”);或者-D key.value.separator.in.input.line=,。
8. 参考资料
(1) 书籍 Jason Venner 《Pro Hadoop》
(2) 书籍 Chuck Lam 《Hadoop in Action》
(3) 书籍 Tom White 《Hadoop The Definitive Guide》
(4) Hadoop分布式缓存例子:书籍《Hadoop The Definitive Guide》 第八章 最后一节“Distributed Cache”
(5) Hadoop Pipes例子:源代码中$HAOOOP_HOME/src/examples/pipes路径下。
(6) Hadoop Pipes资料:
http://developer.yahoo.com/hadoop/tutorial/module4.html#pipes
http://wiki.apache.org/hadoop/C%2B%2BWordCount
原创文章,转载请注明: 转载自董的博客
本文链接地址: http://dongxicheng.org/mapreduce/writing-hadoop-programes/
如何在Hadoop上编写MapReduce程序相关推荐
- 如何在IDEA上编写Spark程序?(本地+集群+java三种模式书写代码)
本篇博客,Alice为大家带来关于如何在IDEA上编写Spark程序的教程. 文章目录 写在前面 准备材料 图解WordCount pom.xml 本地执行 集群上运行 Java8版[了解] 写在前面 ...
- 如何在mac上编写java程序_在mac系统上安装Eclipse,编写java程序
第一步:安装java jre(java 运行环境). 如图所示: 登陆Oralce官网,点击Download选项,找到如图所示界面: 选择Java Runtime Environment(JRE),打 ...
- 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试
原文地址:http://www.cnblogs.com/joyeecheung/p/3757915.html 相关随笔: 点击打开链接 Hadoop-1.0.4集群搭建笔记 用python + ha ...
- 如何在Hadoop上运行TensorFlow【部署】
为什么80%的码农都做不了架构师?>>> 原文链接 : https://www.tensorflow.org/deploy/hadoop 译文链接 : http://www.a ...
- Eclipse helios 上编写arduino程序并进行烧录
源:Eclipse helios 上编写arduino程序并进行烧录
- android用什么更新应用程序,如何在Android上更新应用程序 教你如何更新安卓手机APP...
您从Play商店下载的大多数Android应用程序都会出于各种原因而定期提供更新:添加功能,错误修复,提高安全性...了解如何在Android智能手机上管理应用程序以及如何使它们保持最新. 如果您想要 ...
- ipad1无法安装应用程序_如何在iPad上的应用程序之间拖放
ipad1无法安装应用程序 Whenever you need to share information between apps on an iPad, you probably just copy ...
- 【Hadoop】伪分布式安装---MapReduce程序运行到YARN上,编写MapReduce程序---HDFS yarn
在我的虚拟机(Linux)上安装的Hadoop是2.7.3版本的,安装过程可以参考这个网站,也可以下载. http://hadoop.apache.org/docs/r2.7.6/hadoop-pro ...
- hadoop jar包_计算机毕业设计中hadoop上运行Java程序
点击上方"蓝字",关注我们. 第一种:原生态运行jar包 1,利用eclipse编写Map-Reduce方法,一般引入Hadoop-core-1.1.2.jar.注意这里eclip ...
最新文章
- System commands can run from cmd
- Mac OSX 下高效安装 homebrew 及完美避坑姿势
- trang.jar转换xml到Javabean
- 魅族官宣好消息:魅族16s Pro暮光森林终于要来了
- Python基础——continute与break(循环控制)
- MySQL不应出现的开始声明_备考:2019年9月计算机二级MySQL试题
- canvas浅谈 实现简单的自旋转下落
- python大数据之数据分割(含k折交叉验证)
- STM32的Altium Designer原理图PCB封装库下载
- 201510月职称计算机题目,职称计算机考试模拟题库-Excel试题及答案11
- PMP课程笔记:第9章 项目资源管理
- Pixelmator for Mac如何使用抠..图的功能
- excel 怎么自动往下生成编号
- How DICK’S moved its software development in-house and aced omnichannel retail
- Autodesk 3ds Max 2023安装图文教程
- Windows 11 家庭版、专业版、企业版、教育版、SE 版之间的区别
- 浅谈对dao层的理解
- MNIST是什么鬼?
- Android tv 切换应用,Android TV快捷键切换到其他应用后电视声音仍未中止问题的解决...
- python scripts文件夹里面没有pip.exe怎么办?
热门文章
- 1. Nest Js
- 数据加密和数据签名的本质区别 解释
- GMIS 2017大会邓力演讲:无监督学习的前沿与SPDG方法的优良性
- Ben Horowitz:执行程序有多糟糕,公司倒闭就有多快
- 基于PredictionIO的推荐引擎打造,及大规模多标签分类探索
- 大牛市中大师们如何选股长袖善舞——兼谈本周经济与股市
- 白话Elasticsearch47-深入聚合数据分析之Cardinality Aggs-cardinality算法之优化内存开销以及HLL算法
- 简单分析算法的时间复杂度
- html ppt文件在线播放,[2018年最新整理]如何在PPT中插入html网页.ppt
- 学习笔记Hadoop(四)—— Hadoop集群的安装与部署(1)—— 虚拟机安装、java安装