如何在Hadoop上编写MapReduce程序

 我来答
huanglenzhi
2015-06-26 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517195
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
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分发和执行,结果收集和作业进度监控。
在编写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对。
(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处理进度。
(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中必须实现的函数是

void reduce(K2 key,

Iterator<V2> values,

OutputCollector<K3,V3> output,

Reporter reporter

) throws IOException
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式