MapReduce工作原理Word文档下载推荐.docx
《MapReduce工作原理Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《MapReduce工作原理Word文档下载推荐.docx(10页珍藏版)》请在冰豆网上搜索。
另一个是TaskTracker,JobTracker是用于调度工作的,TaskTracker是用于执行工作的。
一个Hadoop集群中只有一台JobTracker。
在分布式计算中,MapReduce框架负责处理了并行编程中分布式存储、工作调度、负载均衡、容错均衡、容错处理以及网络通信等复杂问题,把处理过程高度抽象为两个函数:
map和reduce,map负责把任务分解成多个任务,reduce负责把分解后多任务处理的结果汇总起来。
需要注意的是,用MapReduce来处理的数据集(或任务)必须具备这样的特点:
待处理的数据集可以分解成许多小的数据集,而且每一个小数据集都可以完全并行地进行处理。
1.2MapReduce处理过程
在Hadoop中,每个MapReduce任务都被初始化为一个Job,每个Job又可以分为两种阶段:
map阶段和reduce阶段。
这两个阶段分别用两个函数表示,即map函数和reduce函数。
map函数接收一个<
key,value>
形式的输入,然后同样产生一个<
形式的中间输出,Hadoop函数接收一个如<
key,(listofvalues)>
形式的输入,然后对这个value集合进行处理,每个reduce产生0或1个输出,reduce的输出也是<
形式的。
一切都是从最上方的userprogram开始的,userprogram链接了MapReduce库,实现了最基本的Map函数和Reduce函数。
图中执行的顺序都用数字标记了。
1)MapReduce库先把userprogram的输入文件划分为M份(M为用户定义),每一份通常有16MB到64MB,如图左方所示分成了split0~4;
然后使用fork将用户进程拷贝到集群内其它机器上。
2)userprogram的副本中有一个称为master,其余称为worker,master是负责调度的,为空闲worker分配作业(Map作业或者Reduce作业),worker的数量也是可以由用户指定的。
3)被分配了Map作业的worker,开始读取对应分片的输入数据,Map作业数量是由M决定的,和split一一对应;
Map作业从输入数据中抽取出键值对,每一个键值对都作为参数传递给map函数,map函数产生的中间键值对被缓存在内存中。
4)缓存的中间键值对会被定期写入本地磁盘,而且被分为R个区,R的大小是由用户定义的,将来每个区会对应一个Reduce作业;
这些中间键值对的位置会被通报给master,master负责将信息转发给Reduceworker。
5)master通知分配了Reduce作业的worker它负责的分区在什么位置(肯定不止一个地方,每个Map作业产生的中间键值对都可能映射到所有R个不同分区),当Reduceworker把所有它负责的中间键值对都读过来后,先对它们进行排序,使得相同键的键值对聚集在一起。
因为不同的键可能会映射到同一个分区也就是同一个Reduce作业(谁让分区少呢),所以排序是必须的。
6)reduceworker遍历排序后的中间键值对,对于每个唯一的键,都将键与关联的值传递给reduce函数,reduce函数产生的输出会添加到这个分区的输出文件中。
7)当所有的Map和Reduce作业都完成了,master唤醒正版的userprogram,MapReduce函数调用返回userprogram的代码。
所有执行完毕后,MapReduce输出放在了R个分区的输出文件中(分别对应一个Reduce作业)。
用户通常并不需要合并这R个文件,而是将其作为输入交给另一个MapReduce程序处理。
整个过程中,输入数据是来自底层分布式文件系统(GFS)的,中间数据是放在本地文件系统的,最终输出数据是写入底层分布式文件系统(GFS)的。
而且我们要注意Map/Reduce作业和map/reduce函数的区别:
Map作业处理一个输入数据的分片,可能需要调用多次map函数来处理每个输入键值对;
Reduce作业处理一个分区的中间键值对,期间要对每个不同的键调用一次reduce函数,Reduce作业最终也对应一个输出文件。
2MapReduce原理
(二)
2.1MapReduce作业运行流程
流程分析:
1)在客户端启动一个作业。
2)向JobTracker请求一个JobID。
3)将运行作业所需要的资源文件复制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客户端计算所得的输入划分信息。
这些文件都存放在JobTracker专门为该作业创建的文件夹中。
文件夹名为该作业的JobID。
JAR文件默认会有10个副本(mapred.submit.replication属性控制);
输入划分信息告诉了JobTracker应该为这个作业启动多少个map任务等信息。
4)JobTracker接收到作业后,将其放在一个作业队列里,等待作业调度器对其进行调度,当作业调度器根据自己的调度算法调度到该作业时,会根据输入划分信息为每个划分创建一个map任务,并将map任务分配给TaskTracker执行。
对于map和reduce任务,TaskTracker根据主机核的数量和内存的大小有固定数量的map槽和reduce槽。
这里需要强调的是:
map任务不是随随便便地分配给某个TaskTracker的,这里有个概念叫:
数据本地化(Data-Local)。
意思是:
将map任务分配给含有该map处理的数据块的TaskTracker上,同时将程序JAR包复制到该TaskTracker上来运行,这叫“运算移动,数据不移动”。
而分配reduce任务时并不考虑数据本地化。
5)TaskTracker每隔一段时间会给JobTracker发送一个心跳,告诉JobTracker它依然在运行,同时心跳中还携带着很多的信息,比如当前map任务完成的进度等信息。
当JobTracker收到作业的最后一个任务完成信息时,便把该作业设置成“成功”。
当JobClient查询状态时,它将得知任务已完成,便显示一条消息给用户。
以上是在客户端、JobTracker、TaskTracker的层次来分析MapReduce的工作原理的,下面我们再细致一点,从map任务和reduce任务的层次来分析分析吧。
2.2Map、Reduce任务中Shuffle和排序的过程
Map端:
1)每个输入分片会让一个map任务来处理,默认情况下,以HDFS的一个块的大小(默认为64M)为一个分片,当然我们也可以设置块的大小。
map输出的结果会暂且放在一个环形内存缓冲区中(该缓冲区的大小默认为100M,由io.sort.mb属性控制),当该缓冲区快要溢出时(默认为缓冲区大小的80%,由io.sort.spill.percent属性控制),会在本地文件系统中创建一个溢出文件,将该缓冲区中的数据写入这个文件。
2)在写入磁盘之前,线程首先根据reduce任务的数目将数据划分为相同数目的分区,也就是一个reduce任务对应一个分区的数据。
这样做是为了避免有些reduce任务分配到大量数据,而有些reduce任务却分到很少数据,甚至没有分到数据的尴尬局面。
其实分区就是对数据进行hash的过程。
然后对每个分区中的数据进行排序,如果此时设置了Combiner,将排序后的结果进行Combia操作,这样做的目的是让尽可能少的数据写入到磁盘。
3)当map任务输出最后一个记录时,可能会有很多的溢出文件,这时需要将这些文件合并。
合并的过程中会不断地进行排序和combia操作,目的有两个:
(1)尽量减少每次写入磁盘的数据量;
(2)尽量减少下一复制阶段网络传输的数据量。
最后合并成了一个已分区且已排序的文件。
为了减少网络传输的数据量,这里可以将数据压缩,只要将press.map.out设置为true就可以了。
4)将分区中的数据拷贝给相对应的reduce任务。
有人可能会问:
分区中的数据怎么知道它对应的reduce是哪个呢?
其实map任务一直和其父TaskTracker保持联系,而TaskTracker又一直和JobTracker保持心跳。
所以JobTracker中保存了整个集群中的宏观信息。
只要reduce任务向JobTracker获取对应的map输出位置就ok了哦。
到这里,map端就分析完了。
那到底什么是Shuffle呢?
Shuffle的中文意思是“洗牌”,如果我们这样看:
一个map产生的数据,结果通过hash过程分区却分配给了不同的reduce任务,是不是一个对数据洗牌的过程呢?
Reduce端:
1)Reduce会接收到不同map任务传来的数据,并且每个map传来的数据都是有序的。
如果reduce端接受的数据量相当小,则直接存储在内存中(缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制,表示用作此用途的堆空间的百分比),如果数据量超过了该缓冲区大小的一定比例(由mapred.job.shuffle.merge.percent决定),则对数据合并后溢写到磁盘中。
2)随着溢写文件的增多,后台线程会将它们合并成一个更大的有序的文件,这样做是为了给后面的合并节省时间。
其实不管在map端还是reduce端,MapReduce都是反复地执行排序,合并操作,现在终于明白了有些人为什么会说:
排序是hadoop的灵魂。
3)合并的过程中会产生许多的中间文件(写入磁盘了),但MapReduce会让写入磁盘的数据尽可能地少,并且最后一次合并的结果并没有写入磁盘,而是直接输入到reduce函数。
3MapReduce原理(三)
3.1物理实体
谈mapreduce运行机制,可以从很多不同的角度来描述,比如说从mapreduce运行流程来讲解,也可以从计算模型的逻辑流程来进行讲解,也许有些深入理解了mapreduce运行机制还会从更好的角度来描述,但是将mapreduce运行机制有些东西是避免不了的,就是一个个参入的实例对象,一个就是计算模型的逻辑定义阶段。
首先讲讲物理实体,参入mapreduce作业执行涉及4个独立的实体:
1)客户端(client):
编写mapreduce程序,配置作业,提交作业,这就是程序员完成的工作;
2)JobTracker:
初始化作业,分配作业,与TaskTracker通信,协调整个作业的执行;
3)TaskTracker:
保持与JobTracker的通信,在分配的数据片段上执行Map或Reduce任务,TaskTracker和JobTracker的不同有个很重要的方面,就是在执行任务时候TaskTracker可以有n多个,JobTracker则只会有一个(JobTracker只能有一个就和hdfs里namenode一样存在单点故障,我会在后面的mapreduce的相关问题里讲到这个问题的)
4)Hdfs:
保存作业的数据、配置信息等等,最后的结果也是保存在hdfs上面。
3.2运行原理
首先是客户端要编写好mapreduce程序,配置好mapreduce的作业也就是job,接下来就是提交job了,提交job是提交到JobTracker上的,这个时候JobTracker就会构建这个job,具体就是分配一个新的job任务的ID值,接