完全解析大数据中MapReduce的运行流程

为什么要学习MapReduce
2004年,谷歌发表了一篇名为《MapReduce》的论文,主要介绍了如何在分布式的存储系统上对数据进行高效率的计算。2005年,Nutch团队使用Java语言实现了这个技术,并命名为MapReduce。时至今日,MapReduce是Apache Hadoop的核心模块之一,是运行在HDFS上的分布式运算程序的编程框架,用于大规模数据集(大于1TB)的并行运算。其中的概念,"Map(映射)"和"Reduce(归约)",是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。


●在过去的很长一段时间里,CPU的性能都会遵循”摩尔定律“,在性能上每隔18个月左右就是提高一倍。那个时候,不需要对程序做任何改变,仅仅通过使用更优秀的CPU,就可以进行性能提升。但是现在,在CPU性能提升的道路上,人类已经到达了制作工艺的瓶颈,因此,我们不能再把希望寄托在性能更高的CPU身上了。


●现在这个时候,大规模数据存储在分布式文件系统上,人们也开始采用分布式并行编程来提高程序的性能。分布式程序运行在大规模计算机集群上,集群是大量的廉价服务器,可以并行执行大规模数据处理任务,这样就获得了海量的计算能力


●分布式并行编程比传统的程序有明显的区别,它运行在大量计算机构成的集群上,可以充分利用集群的并行处理能力;同时,通过向集群中增加新的计算节点,就可以很容易地实现集群计算能力的扩展。

MapReduce主要解决的是分布式文件存储系统上,数据的分布式计算的问题。在上述导读部分我们介绍过一个WordCount的案例,就是一个非常典型的分布式计算的案例。如果我们将所有的需要处理的数据移动到一个节点上进行处理,那么只是在数据传输的过程中就得消耗大量的时间,而且还可能在一台节点存不下这大量的数据。就算是能够存储下,也能够接受数据移动所带来的时间消耗,集群中其他节点的计算资源也都是在闲置的,不能高效率地利用集群。


因此我们就需要进行分布式的计算,将计算程序分发给不同的节点。在每一个节点上处理自己节点的数据,最后将每一个节点的数据处理结果汇总在一起。而在分布式计算的过程中会遇到很多的分布式计算的细节问题,这些问题都是需要开发人员去考虑的。那么如何去解决这些问题呢?


MapReduce是一个开源的、分布式的计算框架,封装了分布式计算程序的实现细节,使得开发人员不需要了解分布式计算底层实现的情况下,就可以去开发一个分布式的计算程序。开发人员只需要将重心放在业务逻辑的实现即可,不需要关注分布式开发的底层细节。因此,对于开发人员来说,可以简化不少的工作量,提高程序开发的效率!

MapReduce的核心思想
1、MapReduce设计的一个理念是“计算向数据靠拢”(移动计算),而不是“数据向计算靠拢”(移动数据)


2、将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,移动到有数据存储的集群节点上,一是可以减少节点间的数据移动开销。二是在存储节点上可以并行计算,大大提高计算效率问题。 因为移动数据需要大量的网络传输开销,尤其是在大规模数据环境下,这种开销尤为惊人,所以移动计算要比移动数据更加经济。


3、MapReduce一个完整的运算分为Map和Reduce两个部分。Map会处理本节点的原始数据,产生的数据会临时存储到本地磁盘。Reduce会跨节点fetch属于自己的数据,并进行处理,产生的数据会存储到HDFS上。


Hadoop的MapReduce核心技术起源于谷歌在2004年发表的关于MapReduce系统的论文介绍。论文中有这么一句话:Our abstraction is inspired by the map and reduce primitives present in Lisp and many other functional languages。这句话提到了MapReduce思想来源,大致意思是,MapReduce的灵感来源于函数式语言(比如Lisp)中的内置函数map(映射)和reduce(规约)。


简单来说,在函数式语言里,map表示对一个列表(List)中的每个元素做计算,reduce表示对一个列表中的每个元素做迭代计算。它们具体的计算是通过传入的函数来实现的,map和reduce提供的是计算的框架。我们想一下,reduce既然能做迭代计算,那就表示列表中的元素是相关的(比如我想对列表中的所有元素做相加求和,那么列表中至少都应该是数值吧)。而map是对列表中每个元素做单独处理的,这表示列表中可以是杂乱无章的数据。这样看来,就有点联系了。在MapReduce里,Map处理的是原始数据,自然是杂乱无章的,每条数据之间互相没有关系;到了Reduce阶段,数据是以key后面跟着若干个value来组织的,这些value有相关性,至少它们都在一个key下面,于是就符合函数式语言里map和reduce的基本思想了。

完全解析大数据中MapReduce的运行流程_第1张图片 

 

MapReduce的运行流程

完全解析大数据中MapReduce的运行流程_第2张图片 

 

Map阶段
1、MapTask进程启动之后,会根据对应的输入分片来处理数据,每一个分片分配一个MapTask来处理。
2、使用客户端指定的InputFormat来读取数据,常用的就是LineRecordReader对象。它会逐行读取分片中的数据,并形成一个键值对。键为行偏移量,值为行记录。我们通常称为
3、将读取到的键值对数据输入到map方法中,进行用户自己的逻辑处理。并输出键值对,我们称为
4、map方法输出的键值对,会被搜集进环形缓冲区。环形缓冲区是内存中的一个字节数组,默认的大小是100M。
5、当环形缓冲区中被写入了80%的数据的时候,会将这80%的部分进行分区、排序,并溢写到磁盘,生成一个文件。在这个过程中,如果上游还有数据产生,将存储在剩余的20%的空间内。如果上游产生数据的速度非常快,剩余的20%也被填充满,并且80%的数据还没有填写完成,此时任务将阻塞,上游不再读取数据,直到溢写文件完成。最终可能会生成多个溢写的磁盘文件。
6、将每一个溢写的磁盘文件合并成为一个文件,在合并的过程中,依然会按照分区、Key进行排序。最终,每一个MapTask生成一个磁盘文件。至此,MapTask执行结束。


Reduce阶段
1、每一个ReduceTask需要去处理一个分区的数据,因此ReduceTask需要到每一个MapTask所在的节点去fetch自己分区的数据。
2、拉取到的数据,如果比较小,会直接保存在内存中,在内存中完成排序,直到达到内存阈值,将其填写到文件中;如果比较大,会直接以文件的形式保存起来。
3、数据拉取完成后,会按照设定好的合并因子进行合并。
4、按照Map阶段输出的的键进行分组,将相同键所对应的所有的值聚合到一起,形成一个集合。
5、将分组之后的键值对>,输入到Reduce方法中,进行逻辑处理。并输出最终的结果
6、将最终的结果,由客户端指定的OutputFormat进行输出。至此ReduceTask结束。


帮助到你的话就点个关注吧~

你可能感兴趣的:(hadoop,mapreduce,大数据)