hadoop 自我学习之MapReduce原理剖析
MapReduce 是一种云计算的核心计算模式,是一种分布式运算的技术,自动将一个大的运算拆分成多个Map和Reduce的方式。
架构层次
MapReduce的应用:10TB的数据
如何统计单词数
如何建立倒排索引
MapReduce 的核心想法是分治算法,就像生活中厨师做饭一样。
Map阶段首先我们有一堆的食材(data),然后要使用(input),作为厨师我们要了解之后分类(split),然后map将食材切片。这就是key-value,前面都是准备阶段。
接下来我们需要跟某些条件,把食材放入不同的制作台,这是shuffle,有了所有的原料之后。Reduce食材拼成最后的成品,最后送给客户Finalize。通过MapReduce,我们能分布式的批量做各种食物
总结下来:MapReduce 就是 来 拿 切 放 拼 送!
Mapreduce 架构
MapReduce的过程是由各个worker来完成的,worker为计算单元集合,worker需要完成的任务由master决定。
这个是统计词频的任务,编号是0,1,2。然后,我们按编号拿各个文档给到Map Workers。这些Workers会把文档中的单词切出来,输出一个个tuple,key是单词,value是出现次数。因为按单词顺序切出来,所以出现次数都是1。接下来,我们把相同的单词放在一起。Reduce会将出现次数拼起来,也就是该单词出现的总次数。最后,我们将所有Reduce的结果输出。完成。这就是一个简单MapReduce实现。
总结:
整个MapTask分为Read阶段,Map阶段,Collect阶段,溢写(spill)阶段和combine阶段
Read阶段:MapTask通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value
Map阶段:该节点主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value
Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果。在该函数内部,它会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中
Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作
Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。shuffle流程详解如下:
MapTask收集map()方法输出的kv对,放到环形缓冲区中
从环形缓冲区不断溢出到本地磁盘文件,可能会溢出多个文件
多个溢出文件会被合并成大的溢出文件
在溢出过程及合并的过程中,都要调用Partitioner进行分区和针对key进行排序
ReduceTask根据自己的分区号,去各个MapTask机器上取相应的结果分区数据
ReduceTask将取到的来自同一个分区不同MapTask的结果文件进行归并排序
合并成大文件后,shuffle过程也就结束了,进入reduce方法
整个ReduceTask分为Copy阶段,Merge阶段,Sort阶段(Merge和Sort可以合并为一个),Reduce阶段。
Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中
Merge阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多
Sort阶段:按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可
Reduce阶段:reduce()函数将计算结果写到HDFS上