前言
Hadoop两大核心组件之一MapReduce的计算框架,它将复杂的、运行于大规模集群上的并行计算过程高度地抽象到了两个函数:Map和Reduce,MapReduce它是属于并发计算框架。
以下我们将了解MapReduce运行原理及过程。
MapReduce基本执行过程
MapReduce执行过程示例说明
在上图中一共有6个map进程和2个reduce进程,一共有8个独立的进程空间,但这个MapReduce跑起来,那么它则需要8个进程空间。它们当中有可能在同一个节点,也有可能是独立不同的节点。根据上面的运行过程一起来解析下它的执行过程。
- 通过节点1,节点2输入文件(HDFS文件系统中的文件)
- MapReduce通过InputFormat来进行对接数据(MapReduce自带的接口,我们只需要开发Map与Reduce行数即可),这个接口主要完成两个功能,第一个就是数据切割(Split),第二个就是记录读取器(Record Reader)
- 那么上图InputFormat接口相当于把原数据一共切割为6个Split,那么就会MapReduce框架就会生成6个Map来处理(结论:即一个Split对应一个Map,所以可以使用Split的个数来控制Map的个数),数据切割它会在合适的位置对原数据(即Block)进行切割,并且保证它的完整性。
- 然后RecordReader会从Split中正确读出一条一条的数据输出作为标准输入调用map方法,由map方法执行计算或者清洗。
- Map输出过程中有一个重要的阶段,即Shuffle,那么Shuffle阶段其实包含以下部分(其实Shuffle阶段也包含Reduce当中的一部分,比如归并)。
- 分区:根据Reduce的数量对key进行hash取模,这个partition处理是在Map当中的Buffer当中实现的,内存缓冲区默认是100m,如果100m内超过了80m,就会把这80m的数据给锁住,然后将这些数据进行排序然后能够清空内存并且写入本地磁盘(也称之为溢写)
- 排序:根据key进行排序(此处是发生在溢写的过程中就会排序好)
- Combiner(则会运行来化简压缩输出的数据,比如当中的一条数据可能在map输出的时候会输出两条数据,那么经过combiner之后最终存储就只会存汇总的结果,前提不能防止扰乱最终的结果)
- 归并:每次溢写都会生成一个新的文件,那么最终处理完之后,map最终还是会把所有溢写的文件合并成一个文件(合并后的文件内容仍然会保持分区与排序的状态)
- Reduce阶段,每个reduce任务开始从多个map上拷贝属于自己partition(map阶段已经做好partition,而且每个reduce任务知道应该拷贝哪个partition;拷贝过程是在不同节点之间,Reducer上拷贝线程基于HTTP来通过网络传输数据)
- 最后,执行reduce阶段,运行我们实现的Reducer中化简逻辑,最终将结果直接输出到HDFS中(因为Reducer运行在DataNode上,输出结果的第一个replica直接在存储在本地节点上)。
总结
通过上面的描述我们看到,在MR执行过程中,存在Shuffle过程的MapReduce需要在网络中的节点之间(Mapper节点和Reducer节点)拷贝数据,如果传输的数据量很大会造成一定的网络开销。而且,Map端和Reduce端都会通过一个特定的buffer来在内存中临时缓存数据,如果无法根据实际应用场景中数据的规模来使用MapReduce,尤其是做大数据两并且计算复杂,有可能很浪费资源,降低了系统处理任务的效率,还可能因为内存不足造成oom问题,导致计算任务失败。