余老师带你学习大数据-Spark快速大数据处理第三章第七节MR内部机制调优

MapReduce基本原理

输入数据是怎么来的

Hadoop将我们的输入数据划分为等长的数据块,被称为输入的分片,Hadoop为每个分片构建一个map任务,并用该任务来运行用户自定的map函数来处理分片中的每一条记录,map结果就是每一条记录输出的结果。

负载均衡

每个分片所需的时间少于处理输入数据所花的时间。因此,如果并行的处理每个分片,且每个分片的数据比较,那么整个处理过程将获得更好的负载均衡。因为我们一台快计算机它能够处理的数据分片肯定比一台慢的计算机处理的多,而且成一定的比例。如果说,我们把输入分片分的比较细,那么这样,可以达到某种负载均衡或者多的可以承载多的,少的承载少的。但是,如果我们的分片比较大,那么我们就会卡死在这个节点上。比如说,有10个分片需要承载,要用1为单位的承载,可以承载为10份;如果用3为单位的承载,3份还多1份,没法平均起来。也就是分片要小,我们才能做的更好的负载均衡。如果输入分片太小,这个整个输入性能不一定越好,因为在管理分片,在运行map任务的时间可能比处理分片的时间还要多,那么,就是相当于拣了芝麻丢了西瓜,那么这个分片过小,在这里是不划算的。那要怎么样才能产生一个均衡的结果,之前讲的HDFS文件是分为许多的数据块,数据块是承载在DataNode节点上。比如说,每个数据块都是128兆、64兆这种数据块是比较大的,因为我们面临的问题是大数据集的情况,且每个数据块将占用我们NameNode的一部分资源,将数据块切的太小,我们将会受到一定的损失,特别是NameNode的性能损失,所以我们要适中,这是架构层面的考虑。而且Map做的时候都是本地化,什么是数据本地化,在做大数据处理的时候,要借用本地化的处理措施来获得性能,在前面我们的hadoop3的目标中我们讲过,计算要尽可能的靠近数据,而且计算搬移的性能较为容易一些,数据很难搬移。那么最恰当的目标是将计算分布在数据所处理的节点上,那么Map可以达到这个目标。我们在数据所在的节点上执行Map线程将数据存储在节点所在的缓存里。因此就可以在Map端节约网络资源,集群的带宽资源。此外,还要明确一个概念,为什么最佳的分片大小和块的大小相同,而不是和两个块的大小?是因为,如果分片跨越两个数据块任何一个HDFS节点基本上不可能同时存储这两个数据块,因为对于任何HDFS节点也就是DataNode不可能有同时存储两个数据块,这个数据可靠性的要求。

MapReduce优点

1、可以在MapReduce里的job中设置combiner。
2、Map将数据存在本地的系统里,这个过程并不是简单的写到磁盘。在我们软件设计里面就会经常用的这一点,就是有一个循环的缓冲区,这个缓冲区是内存的,它的速度和性能比磁盘的要高,在每一个Map任务的机器上我们设置一个循环的缓冲区,将Map的结果写到缓冲区,当这个缓冲区写满之后,再将写到溢出到文件里面去,这个过程是可以控制的,每个缓冲的区的大小,都是可以控制的。
3、Reduce的过程就相当于先做拷贝再做计算,在拷贝的过程就是做一个合并,是一个逐步的拷贝,因为在Map的过程就是缓慢的,合并次数可以设定。

MapReduce内部机制

在这里插入图片描述

程序过程

输入有三个切片,对应的map结果是分别是:Dear,1、Hello,1、World,1和World,1、Hello,3、Dear,2以及World,1、Hello,2、World,1。当我们的shuffle进程完成之后,我们的数据已经get到了,比如dear1和dear2,为了减少数据传输量,在我们做work的时候,将dear1和dear2做一次运算,那么只传输一条记录dear3,做这项功能的叫combiner。之后有两个sort,by key和by value第一个sort是根据key做排序,第二个sort是根据value做排序,做完sort之后,送到给reduce,reduce在将数据写到output里面。

程序原理

如果将两个数据块分配同一个Map那么将可能产生网络的传输,会降低Map传输的性能。虽然将数据存在了Map的DataNode的本地节点,也就是Map放在的本地的文件系统里。而不是HDFS中,这是因为HDFS需要存到用于备份,这样又产生了网络层的数据传输,所以说,将Map的结果存到本地的文件系统里面。因此,Reduce任务需要有一个shuffle过程,就是混洗过程。混洗过程会产生一个网络传输,混洗的过程将Map所在的节点上的结果数据,拷贝到Reduce所在的节点上。而且,因为有多个Reduce,每个Reduce要处理Map结果的子集。因为Map结果有很多的key,需要有一个分区器,把Map结果挂分到Reduce上,也就是选取那些key给哪一个Reduce,在这个分区环节已经确定了。同时这也是Map和Reduce这两个函数的耦合点,因为在做Map的时候,需要知道,这个分区是怎么样做的。所以说, Map的输出要做分区,有了个这个分区之后哪些Map需要送达给哪个Reduce,或者反过来说,我们的shuffle这些线程才能够知道我们去取哪些分区给哪一个Reduce。 在之间做的例子中,输出文件中会有一个part -r -00000结果文件,既然有00000文件,肯定也会有00001文件,是因为做一个Reduce那么就会输出一个结果,相当于输出了一个结果的分区,所以会有多个part-r的输出。

关键总结

1,排序(Shuffle 阶段):排序是MapReduce的默认行为,两次排序行为:第一次在Map的环形缓冲区中(排序后分区),第二次在Reduce的合并切片数据后(排序后分组)
2,分区(Shuffle 阶段):确保相同key的数据分到同一个Reduce中3,分组(Reduce阶段):确保相同key的数据进入同一个reduce()方法迭代器中
4,合并(Shuffle 阶段):把所有溢写的临时文件进行一次合并操作,以确保一个Map 最终只产生一个中间数据文件。
5,多次写磁盘的时机:1、多次溢写的小文件;2、小文件排序合并;3、分区后形成的数据块等待Reduce拉取;4、Reduce拉取每台map所在机器上的数据块;5、Reduce合并所有的数据块进行排序分组

详细学习内容可观看Spark快速大数据处理扫一扫~~~或者引擎搜索Spark余海峰
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45810046/article/details/108884341