什么是MapReduce?
MapReduce是一个分布式计算框架,以可靠,容错的方式在大型集群(数千个节点)上并行处理大量数据(多为TB级数据)。
MapReduce的主要思想是:分久必合
MapReduce的核心思想是:把相同的key分成一组,调用一次Reduce方法。
一、MapReduce分布式计算原理
理论上block大小=split切片大小=map task
实际上split的大小比blcok大几kb或小几kb,因为有部分数据会被切割在其他block中
shuffle write阶段:
首先,Map task将处理后的每一条记录打上标签,其目的就是让此记录将来让哪个Reduce task处理。简单理解就是打标签的目的是为了分区,此次分区是基于偏移量进行,即分出多少个区。然后根据key的HashCode与Reduce task的个数取模,从而将key值相同的记录放在一个分区。此时每一条记录就由三部分组成包括分区号、key、value。
其次,Map task将一条条的记录写入buffer中,当写入数据的大小达到80M,此时这80M的内存将会被封锁,封锁的过程中,线程会对内存中的数据进行combiner(小聚合),然后进行排序(排序规则为二次排序,首先根据分区号,然后根据key),然后将分区号相同的数据放在一起,此时分区内的数据是有序的。待combiner、排序完成后,就开始溢写数据到磁盘,这时候磁盘文件就是一个根据分区号分好区,并且内部有序的文件。
最后,Map task会将磁盘上的小文件合并成一个大文件,在合并的过程中,使用归并排序算法,将小文件合并成一个有序的大文件。每一个Map task都会执行同样的操作,并产生一个有分区并且分区内部有序的文件。
shuffle red阶段:
首先,Reduce task去Map端读取相应的分区数据,然后将分区后的数据写入到内存中,内存满后就会溢写,在溢写之前会进行排序,当所有的数据读取过来后,Reduce task会将溢写的小文件排序、合并成一个有序的大文件。最后每一组数据会调用reduce函数,产生结果。
产生一个有序大文件的目的:
为了提高分组的效率。
二、MapReduce1.X运行流程
- client将Application打成jar包,然后交给JobTracker;
- 为了遵循计算向数据移动的原则,JobTracker会向NameNode发送请求,询问block的位置信息;
- JobTracker收到block的列表信息后,会向有数据的TaskTracker发送信息,请求分配资源。即启动计算进程,供map task进行计算。每一个map task计算完成后,都会产生一个磁盘文件;
- JobTracker调用Reduce Task去Map端的分区拉取数据,拉取成功之后将最终的结果写入结果文件,然后返回给客户端。
JobTracker的作用:
- 负责资源调度(主节点)
- 负责任务调度(主节点)
问题:
- 负载过高,容易发生单点故障
- 与MapReduce的耦合度过高,若spark也要运行到这套框架上,需要自己去实现,故此集群就存在两套资源调度器,从而出现资源隔离问题和资源抢占问题。
三、MapReduce2.X YARN运行原理
- Client拿到Application计算文件的路径后,找NameNode获取每一个block的位置,获得blcok的报表;
- Client向RM发送请求,为ApplicationMaster申请资源;
- RM接受客户端的请求,然后查看哪个节点资源充足,如果大部分节点资源都充足,那就随机找一台节点启动container容器,若大部分节点都资源紧张,则无法启动;
- 例如在node01上规划出一个container以后,NameNode会在容器中启动一个ApplicationMaster(主要负责任务调度);
- Client会将NameNode生成的报表发送给ApplicationMaster;
- ApplicationMaster拿到报表后,根据报表去找RM申请资源,RM会查看哪台节点资源充足,然后启动caontainer容器,在container中启动Yarn-child;
- ApplicationMaster会分发map task到各个Yarn-child中执行,map task执行完成后,会产生磁盘文件(每一个map task会产生一个磁盘文件),然后ApplicationMaster会调用Reduce task去进行计算,待Reduce task计算完成后,将执行结果写入结果文件,然后返回给客户端。