在MapReduce运行过程中,在上层主要有四个主体:
客户端:提交MR任务
JobTracker:协调作业的运行,主类为JobTracker
TastTracker:运行作用划分后的任务,主类为TastTracker
共享文件系统:在其他实体之间共享文件,一般为HDFS
MR工作机制
1.提交作业:
客户端启动一个Job;并向JobTracker请求一个作业ID,JobTracker检查作业输出(有没有指定输出路径、输出目录是否已存在)计算作业的输出切片;JobTracker会返回一个作业ID和资源的提交路径;客户端将资源(jar文件、xml配置文件、分片信息)提交到共享文件系统上;客户端向JobTracker提交Job。
2.作业调度:
JobTracker将提交的作业放在内部的任务队列,作业调度器对其调度(具体的调度策略之后说明),并初始化作业(创建一个表示正在运行作业的对象,原来封装任务与记录信息);JobTracker的作业调度器从共享文件系统中获取客户端的分片信息,创建任务执行列表(map/reduce/作业清理任务);TaskTracker与JobTracker保持心跳通信,报告是否主备好接受任务,若准备好则将任务分配到各个TaskTracker。
3.运行任务:
TaskTracker从HDFS中获取任务资源,将jar包本地化并解压到工作目录,创建TaskRunner实例;TaskRunner启动一个JVM。运行map/reduce任务;
TaskTracker通过心跳向JobTracker汇报任务进度,JobTracker合并后发送给客户端;
一个MR任务执行流程
Map端
1.InputFormat(默认实现类为TextInputFormat)读取外部数据,调用RecordReader.read()方法读取,返回k,v键值对;
2.读取的k,v键值对传入map方法中,在其中执行响应逻辑;
3.调用context.write()方法,outputCollector会将map()计算结果写入环形缓存区;
4.环形缓存区是一个环形数组(一般为100M),缓存达到阈值(80%),spiller组件将内容将溢出到磁盘,溢写过程中map输出仍会写入环形缓存区,当环形缓存区填满后会阻塞直到溢出完成。
5.溢写过程中会按照定义分区(默认为HashPartition),并按key.comapreTo()排序,若有combiner则会执行combiner。这个过程生成的小文件仍在map端机器上。
6.将小文件合并,变成分区内有序的大文件,这会再一次调用combiner。
7.Reducer会按照分区从响应map task中拉去数据
Reduce端
1.因为reduce任务需要集群上若干个map的数据,所以每个map任务完成便开始并行(默认为5)拉去数据;(若map端输出很小,会被复制到reduce任务JVM的内存,当达到阈值时会被溢出到磁盘);
2.通过GroupingComparator()分辨同一组数据,将其发给reduce(k,iterator),多个数据合并成一组时只会取第一个kay;
3.调用context.wriite()方法,会让OutPutFormat调用write()方法将处理结果存入数据仓库,写的只有一个分区的文件。
YARN(MR2)工作机制
MRv1存在各种局限:
扩展性差:在 MRv1 中,JobTracker 同时兼备了资源管理和作业控制两个功能,这 成为系统的一个最大瓶颈,严重制约了 Hadoop 集群扩展性。
可靠性差:MRv1 采用了 master/slave 结构,其中,master 存在单点故障问题,一旦 它出现故障将导致整个集群不可用。
资源利用率低:MRv1 采用了基于槽位的资源分配模型,槽位是一种粗粒度的资源 划分单位,通常一个任务不会用完槽位对应的资源,且其他任务也无法使用这些空 闲资源。此外,Hadoop 将槽位分为 Map Slot 和 Reduce Slot 两种,且不允许它们之 间共享,常常会导致一种槽位资源紧张而另外一种闲置(比如一个作业刚刚提交时, 只会运行 Map Task,此时 Reduce Slot 闲置)。
无法支持多种计算框架:随着互联网高速发展,MapReduce 这种基于磁盘的离线计 算框架已经不能满足应用要求,从而出现了一些新的计算框架,包括内存计算框架、 流式计算框架和迭代式计算框架等,而 MRv1 不能支持多种计算框架并存。YARN将JobTracker资源管理和作业控制两个功能分别交给ResourceManager与MRAppMaster
工作角色:
客户端:提交作业
ResourceManager:资源调度(主要包括AppMaster和调度器(Scheduler))
NodeManger:启动和监视节点的计算容器
MRApplicationMaster:协调运行作业中的任务
1.客户端启动一个Job;
2.客户端向ResourceManager请求一个新作业,随后ResourceManager向客户端返回一个作业ID和资源提交路径;
3.客户端将job所需资源(jar包、xlm配置文件、分片信息)提交到共享文件系统(HDFS)指定路径;
4.客户端向ResourceManager提交一个Job;
5.ResourceManager通过调度器选择一个适合的nodemanager创建一个容器,在其中启动MRAppMaster进程(该进程由ResourceManager中的AppsMaster启动);
6.MRAppMaster将作业初始化,创建多个对象对任务进行跟踪;
7.MRAppMaster从共享文件系统中获取分片信息,为每个分片创建map任务以及指定的reduce任务。若任务很小,会与MRAppMaster在同一个JVM中运行(少于10个mapper且只有1个reducer且输入大小小于一个HDFS块,则作为uber任务运行);
8.若作业很大,MRAppMaster会为所有的map与reducer任务向ResourceManager申请资源,请求map数据本地化信息及分片信息;
9.容器分配完成后,MRAppMaster会与node manager通信启动容器,MRAppMaster决定哪些nodemanager运行map/reducer任务(实际的任务在yarnchild中运行)
10.node manager从共享文件系统中获取job相关资源;
11.运行map/reducer任务;
12.状态更新:任务状态周期性向MRMaster汇报,客户端定期查询MRAppMaster获得任务状态。