MapReduce原理

什么是MapReduce?

         Hadoop MapReduce是一个软件框架,基于该框架能够容易地编写应用程序,这些应用程序能够运行在由上千个商用机器组成的大集群上,并以一种可靠的,具有容错能力的方式并行地处理上TB级别的海量数据集。这个定义里面有着这些关键词

1.软件框架
2.并行处理
3.可靠且容错
4.大规模集群
5.海量数据集

MapReduce做什么?

         MapReduce擅长处理大数据,它为什么具有这种能力呢?这可由MapReduce的设计思想发觉。MapReduce的思想就是“分而治之”。MapReduce的核心思想:“相同”的key为一组,调用一次reduce方法,方法内迭代这一组数据的计算。

  1. Mapper负责“”,即把复杂的任务分解为若干个“简单的任务”来处理。“简单的任务”包含三层含义:

    一是数据或计算的规模相对原任务要大大缩小;
    二是就近计算原则,即任务会分配到存放着所需数据的节点上进行计算;(减少传输)
    三是这些小任务可以并行计算,彼此间几乎没有依赖关系。
    
  2. Reducer负责对map阶段的结果进行汇总。至于需要多少个Reducer,用户可以根据具体问题,通过在mapred-site.xml配置文件里设置参数mapred.reduce.tasks的值,缺省值为1。

MapReduce由Map端和Reduce端两个阶段组成。

MapReduce原理
.
流程分析:
.

1.首先是数据的切片

  1. 一个Map Task一次处理一个Split切片,一般来说Spilt≈block块=128M
  2. 因为block块中数据以字节形式存放,当放UTF-8形式的中文时(3字节),block块的最后可能会切割一个文字,造成乱码
  3. 所以为了解决它,split切片取比block多一条数据或者比block块少一条数据。

2.Map的处理

MapTask读到的数据是key-value形式的数据,key是数据在block块中的偏移量,value就是数据,在Map的处理时,会对key-value进行某些操作,形成新的key-value键值对,所以此时的key已经不是偏移量了。

3.shuffle write的三个处理

什么是shuffle?
走网络传输的过程,把相同的数据放入一类,即shuffle洗牌的功能。

3.1为Map Task产生的数据打标签

  1. 打标签的目的就是为了分区,让着一条数据知道将来被送往哪个Reduce Task处理。
  2. 由默认的分区器HashPartitioner进行分区,它的策略是根据Map输出的key的HashCode值%Reduce Task的个数的值来确定每个key-value键值对所在的分区。

3.2打过标签的数据一条条写入Buffer in memory

          Memory一共有100M大,Map Task一条一条的往buffer中去写,一旦写入到80M,此时80M的内存会*,*后对内存中的数据进行combiner(小聚合)
buffer中的每一条数据=分区号+key+value

3.3在内存被*后对数据进行combiner

          小聚合将key值相同的合并

3.4排序

          将内存80M的数据根据分区号排好序,再在分区内根据key大小排序,在内存中形成一个有分区的内部有序的数据,此时,为了不造成阻塞,其他的数据写入内存的剩余的20M中。

3.5溢写

          当内存中的数据排好序之后便会把这个80M的数据溢写到磁盘上,每进行一次溢写就会产生一个小文件,此时的磁盘上的文件就是根据分区号分好的,内部有序的。

3.6合并

          Map Task计算完毕后,会将磁盘上的小文件合成一个大文件,在合并的时候会使用归并排序的算法,将各个小文件合并成一个有分区的并且分区内部有序的大文件。
.

4.shuffle read

4.1将分区数据写入内存中

          去Map端读取相应的分区数据,一个Reduce只处理一个分区内的数据,将分区的数据写入到内存中,内存满了(1G的70%=96%+4%),当96%的内存满了,96%的内存会*,此时其他的数据继续写入4%的内存,96%内的数据会先进行排序(归并)

4.2溢写

          内存满了,排序好了,就要溢写到磁盘,形成有序的文件。

4.3合并

          当所有的数据读取过来以后,会将溢写产生的磁盘小文件合并成一个有序的大文件。

5.进行Reduce Task

          核心思想:“相同”的key为一组,调用一次reduce方法,方法内迭代这一组数据的计算。
此时Reduce里面的所有数据都是同一分区的,然后它会对相同key值的内容进行合并计算(调用reduce方法),形成输出结果。