MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。MapReduce采用”分而治之”的思想,把对大规模数据集的操做,分发给一个主节点管理下的各个分节点共同完成,而后经过整合各个节点的中间结果,获得最终结果。简单地说,MapReduce就是”任务的分解与结果的汇总”。程序员
MapReduce架构算法
先来看一下MapReduce1.0的架构图编程
上图中的TaskTracker对应HDFS中的DataNode,数组
在MapReduce1.x中,用于执行MapReduce任务的机器角色有两个:一个是JobTracker;另外一个是TaskTracker,JobTracker是用于调度工做的,TaskTracker是用于执行工做的。一个Hadoop集群中只有一台JobTracker。架构
流程分析app
在客户端启动任务,客户端向JobTracker请求一个Job ID。分布式
将运行任务所须要的程序文件复制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客户端计算所得的输入划分信息。这些文件都存放在JobTracker专门为该任务建立的文件夹中。文件夹名Job ID。ide
JobTracker接收到任务后,将其放在一个队列里,等待调度器对其进行调度,看成业调度器根据本身的调度算法调度到该任务时,会根据输入划分信息建立N个map任务,并将map任务分配给N个TaskTracker(DataNode)执行。函数
map任务不是随随便便地分配给某个TaskTracker的,这里有个概念叫:数据本地化(Data-Local)。意思是:将map任务分配给含有该map处理的数据块的TaskTracker上,同时将程序JAR包复制到该TaskTracker上来运行,这叫“运算移动,数据不移动”。而分配reduce任务时并不考虑数据本地化。oop
TaskTracker每隔一段时间会给JobTracker发送一个Heartbeat(心跳),告诉JobTracker它依然在运行,同时心跳中还携带着不少的信息,好比当前map任务完成的进度等信息。当JobTracker收到做业的最后一个任务完成信息时,便把该做业设置成“成功”。当JobClient查询状态时,它将得知任务已完成,便显示一条消息给用户。
以上是在客户端、JobTracker、TaskTracker的层次来分析MapReduce的工做原理的,下面咱们再细致一点,从map任务和reduce任务的层次来分析分析吧。
MapReduce运行流程
以wordcount为例,运行的详细流程图以下
1.split阶段
首先mapreduce会根据要运行的大文件来进行split,每一个输入分片(input split)针对一个map任务,输入分片(input split)存储的并不是数据自己,而是一个分片长度和一个记录数据位置的数组。输入分片(input split)每每和HDFS的block(块)关系很密切,假如咱们设定HDFS的块的大小是64MB,咱们运行的大文件是64x10M,mapreduce会分为10个map任务,每一个map任务都存在于它所要计算的block(块)的DataNode上。
2.map阶段
map阶段就是程序员编写的map函数了,所以map函数效率相对好控制,并且通常map操做都是本地化操做也就是在数据存储节点上进行。本例的map函数以下:
publicclassWCMapperextendsMapperLongWritable,Text,Text,IntWritable{@Override protectedvoidmap(LongWritablekey,Textvalue,Contextcontext)throwsIOException,InterruptedException{ Stringstr=value.toString(); String[]strs=StringUtils.split(str,'');for(Strings:strs){ context.write(newText(s),newIntWritable(1)); } } }
根据空格切分单词,计数为1,生成key为单词,value为出现1次的map供后续计算。
3.shuffle阶段
shuffle阶段主要负责将map端生成的数据传递给reduce端,所以shuffle分为在map端的过程和在reduce端的执行过程。
先看map端:
map首先进行数据结果数据属于哪一个partition的判断,其中一个partition对应一个reduce,通常经过key.hash()%reduce个数来实现。
把map数据写入到Memory Buffer(内存缓冲区),到达80%阀值,开启溢写进磁盘过程,同时进行key排序,若是有combiner步骤,则会对相同的key作归并处理,最终多个溢写文件合并为一个文件。
reduce端:
reduce节点从各个map节点拉取存在磁盘上的数据放到Memory Buffer(内存缓冲区),同理将各个map的数据进行合并并存到磁盘,最终磁盘的数据和缓冲区剩下的20%合并传给reduce阶段。
4.reduce阶段
reduce对shuffle阶段传来的数据进行最后的整理合并
publicclassWCReducerextendsReducerText,IntWritable,Text,IntWritable{@Override protectedvoidreduce(Textkey,IterableIntWritablevalues,Contextcontext)throwsIOException,InterruptedException{intsum=0;for(IntWritablei:values){ sum+=i.get(); } context.write(key,newIntWritable(sum)); } }
MapReduce的优缺点
优势:
易于编程;
良好的扩展性;
高容错性;
4.适合PB级别以上的大数据的分布式离线批处理。
缺点:
难以实时计算(MapReduce处理的是存储在本地磁盘上的离线数据)
不能流式计算(MapReduce设计处理的数据源是静态的)
难以DAG计算MapReduce这些并行计算大都是基于非循环的数据流模型,也就是说,一次计算过程当中,不一样计算节点之间保持高度并行,这样的数据流模型使得那些须要反复使用一个特定数据集的迭代算法没法高效地运行。
原文转载自:http://blog.itpub.net/31557424/viewspace-2220234/