MapReduce编程模型
1 Hadoop MapReduce介绍
古时候,人们用牛来拉重物,当一头牛拉不动一根圆木的时候,他们不曾想过培育个头更大的牛。同样,我们也不需要尝试更大的计算机,而是应该开发更多的计算系统。
——格蕾丝·霍珀
在计算机历史上出现太多的某某之父,终于有一位女士说话了,说上面这句话的人就是格蕾丝·霍珀。
格蕾丝·霍珀(Grace Hopper),于1906年出生于美国纽约,是杰出的计算机科学家,计算机软件工程第一夫人,作为Cobol语言的主要设计者,格蕾丝·霍珀被称为Cobol之母。1934年获得耶鲁大学数学博士学位,美国海军将军。格蕾丝·霍珀是著名的女数学家和计算机语言领域的领军人物。她也是第一个发现bug的人。
我们套用软件工程第一夫人的话,当数据量非常大时,我们不是培育一头更强大的象,这样的大象很难培育,或者说成本很高,我们应该使用一群象来分食这些数据。这就是分而治之的原则,这正是Hadoop中MapReduce框架的基本思路,因此,我们从本节开始来探讨MapReduce的内容。
我们将理解什么是MapReduce,以及它是如何工作的,什么是Mapper,Reducer,shuffle和sort等等,对分而治之思想有更深层次的认识。
2 什么是MapReduce
MapReduce是Hadoop的数据处理层。MapReduce的编程模型是将大规模的数据处理工作拆分成相互独立的任务,然后并行处理。你需要将你的业务逻辑描述成MapReduce模型,那么剩下的事情就由框架来处理。用户向Master节点提交的工作(完整的作业),会被分成小工作(任务),并且指定给slave节点执行。
MapReduce程序的编程风格受处理数据列表的函数式编程结构影响。在MapReduce中,我们从列表中获取输入,然后转换成输出,这个输出仍旧是一个列表,这就是Hadoop的核心。Hadoop如此强大和高效,就是由于MapReduce在这个过程中做了并行处理。
我们接下来会介绍MapReduce过程,MapReduce数据流,以及为什么MapReduce是最好的数据处理模型。
2.1 进一步理解Hadoop MapReduce
我们已经就MapReduce有了最基本的了解,我们接下来将深入理解MapReduce的工作原理。
Map-Reduce将工作拆分成小的部分,每个部分都可以在服务器集群中并行处理。一个问题可以被拆分成大量的更小的问题,每个小的问题都能够给出独立的输出。这些独立的输出进一步被处理,从而给出最终的输出。
Hadoop Map-Reduce是可缩放的,并且可以跨多个计算机。很多小机器去处理那些不适合用大机器处理的任务。接下来我们将介绍重要的MapReduce术语。
2.2 Apache MapReduce术语
接下来我们将理解MapReduce的各种术语及概念,什么是Map和Reduce,什么是Job(作业),task(任务),task attempt(任务尝试)等等
Map-Reduce是Hadoop的数据处理组件。Map-Reduce程序将输入数据元素列表转换成输出数据元素列表。Map-Reduce程序执行两次这样的过程,使用两次不同的列表处理风格:
- Map
- Reduce
在Map和Reduce中间有一个小阶段叫Shuffle(洗牌)和Sort(排序)。
接下来让我们理解MapReduce中使用的基本术语。
- 什么是MapReduce Job(作业)
MapReduce Job(或者说是一个完整的程序)是在一个数据集上进行Mapper和Reducer的执行过程。这个执行过程分为Map和Reduce两个阶段。MapReduce Job就是客户端想要执行的工作。它包括输入数据,MapReduce程序以及配置信息。客户端需要提交输入数据,编写MapReduce程序并且设置配置信息(一些是在Hadoop安装时,通过配置文件提供还有一些配置由程序自己进行设置,这样的设置通常针对具体的MapReduce job)。
- 什么是MapReduce中的Task(任务)
MapReduce中的Task指的是在一个数据片段上执行Mapper或者Reducer的过程。它也称为Task-In-Progress(TIP)。这里的数据处理就是mapper或者reducer过程。
- 什么是Task Attempt(任务尝试)
Task Attempt是一个特殊的实例,它在一个节点上尝试执行一个Task(任务)。而且任何机器随时都可能宕机。几个例子来说,在数据处理过程中,如果某台机器宕机,框架将重新调度这个任务在其他节点上执行。这个重新调度过程也不是无限的,它有一个上限,任务尝试的默认次数是4次。如果一个任务(Mapper或者Reducer)失败4次,那么这个job(作业)就被认为是一次失败的Job。对于高优先级的作业或者大型作业,这个任务尝试次数会加大一些。
2.3 Map概述
下面我们来介绍MapReduce编程模式中的第一阶段Map抽象,以及什么是map/mapper,mapper的输入是什么,如何处理数据,mapper的输出是什么。
map接受键值对作为输入,无论数据是结构化还是非结构化形式,框架都将这些输入数据转换成键和值。
- 键(key)是到输入值的引用
- 值(value)是要操作的数据集
Map处理:
- 用户定义的函数-用户根据它所处理的数据编写一个定制的业务逻辑。
- 对输入的每个值进行处理
Map产生一个新的键值对列表:
- Map的输出被称为中间输出
- 可以和输入的键值对类型不同
- map的输出会存储在本地磁盘,而且将在本地磁盘完成shuffle操作(洗牌)
2.4 Reduce概述
下面我们来介绍MapReduce的第二个阶段Reducer。我们要了解Reducer的输入是什么,reducer做了怎样的工作,它的输出是什么。
Reduce接受由Map阶段生成的中间键值对作为输入,对Mapper的输出结果进行处理。通常在reducer中,我们进行聚合或者求和类运算。
- Map生成的数据将作为reducer的输入
- 提供给reduce的键值对已经按key进行排序
Reduce处理:
- 用户自定义的函数-在这里用于也可以写定制的业务逻辑并得到最终的输出
- 对给定key的值(是一个列表)做迭代处理。
Reduce产生一个最终的键值对列表:
- Reduce输出被称为最终输出
- 可以和输入的键值对类型不同
- Reduce的输出会存储在HDFS中
2.5 Map和Reduce是如何在一起工作的
下面我们来解释Hadoop Map和Reduce是如何在一起工作的。
提交给mapper的输入数据会经过mapper中用户定义的函数进行处理。所有需要的复杂业务逻辑都将在mapper层实现,mapper中进行的大量处理过程都会并行处理,其数量要大于reducer的数量。mapper生成的输出数据将作为中间数据,提供给reducer作为输入。
中间结果将由reducer中用户定义的函数进行处理,并最终生成输出。在reducer中处理任务就少很多。最终输出会存储在HDFS中,而且这些结果也会像普通数据一样按复制因子要求进行复制。
2.6 MapReduce数据流(DataFlow)
下面我们来介绍MapReduce的数据流,mapper是真有获取输入数据,mapper又如何处理这些数据,mapper会将数据写到哪里,mapper将数据提交给reducer节点时如何进行shuffle,reducer在哪里运行,reducer会处理什么类型的数据等等。
在上图中,有3个slave节点,所有3个slave上都会有mapper运行,然后会在任意一个slave上运行reducer。在上图所显示的reducer是运行在不同的机器上,但实际上,它只能运行在mapper节点上。
下面我们来讨论map阶段:
mapper的输入每次是一个数据块(block)(默认split=block)。
mapper的输出会写到此mapper运行机器的本地磁盘。一旦完成map,中间输出结果会传输到reducer节点(将要运行reducer的节点)。
Reducer是数据处理的第二个阶段,在这个阶段,用户可以编写他自己的业务逻辑。reducer的最终输出会写到HDFS中。
默认情况下,在一个slave上一次会同时运行2个mapper,当然也可以由于需求不同,运行更多的mapper。这取决于很多因素,比如datanode硬件,块大小,机器配置等等。但是,mapper数量的增加也不能超出限制,这样会降低性能。
Hadoop Mapreduce的Mapper会将输出写入到它所工作机器的本地磁盘。这些是临时数据。mapper的输出也被称为中间输出。所有mapper都会将输出写到本地磁盘。当第一个mapper完成后,数据(mapper的输出)会从mapper节点传输到reducer节点。mapper输出的数据移动到reducer节点的过程也叫洗牌(shuffle)。
reducer也仅能部署到dananode节点。所有mapper的输出都将汇集给reducer。所有来着不同mapper的输出都会被整合作为reducer的输入。这个输入也位于本地磁盘。Reducer是另外一个处理过程,在这里,你也可以写定制的业务逻辑。这是第二阶段的处理过程。我们通常在这里进行聚合,求和等操作。reducer会给出最终的输出,并将其写入到HDFS。
Map和reduce是两个处理阶段。一个阶段完成,就会进入下一个阶段。mapper处理完成之后,才开始reducer处理过程。
尽管1个数据块默认有3份不同的存储位置,但是框架仅允许1个mapper处理一个数据块。因此,仅有1个mapper处理3个副本中的一个特地数据块。每个mapper的输出会传递给集群中的每个reducer,也就是说,每一个reducer会从所有mapper接收输入。
一个mapper的输出会经过partitioner(分区管理器)进行分区和过滤,从而划分到很多分区。根据特定条件,分区中的每条记录都将由一个reducer处理。Hadoop使用键值对原则,也就是说,mapper和reducer以键值对的形式接受输入,并且同样以键值对的形式进行输出。
2.7 MapReduce中的数据本地化
接下来我们将了解什么是数据本地化,“移动计算去靠近数据,而不是向计算移动数据”。应用程序的请求的计算靠近它所操作的数据,这样才是更高效的方式,尤其是数据量非常巨大的情况。这样可以减少网络阻塞,提高系统吞吐量。把计算向靠近数据的地方移动相比把数据向应用程序运行的地方移动要更好。因此,HDFS为应用程序提供了接口,让它们能够移到到数据所在的地方。
Hadoop要处理大量数据,显然不适合在网络上移动这些数据,因此提出革命性的原则,就是向数据移动算法,而不是让数据靠近算法,这就是数据本地化。
3 总结
MapReduce使Hadoop变得强大。数据本地化提升了Hadoop的性能。