YARN架构
YARN是Hadoop2.0版本新引入的资源管理系统,直接从MR1演化而来。核心思想:将MP1中JobTracker的资源管理和作业调度两个功能分开,分别由ResourceManager(全局)和ApplicationMaster(每个应用程序都有一个)进程来实现。YARN的出现,使得多个计算框架可以运行在一个集群当中(每个应用程序对应一个ApplicationMaster)。目前可以支持多种计算框架运行在YARN上面比如MapReduce、Storm、Spark、Flink等。
YARN的架构主要由ResourceManager、NodeManager、ApplicationMaster和Container组成。
YARN上的MR相较于MR1.0包含更多的实体:
- YARN资源管理器(ResourceManager),负责协调集群上的计算资源的分配
- YARN节点管理器(NodeManager),负责启动和监视集群中机器的计算容器(Container)
- MapReduce应用程序master(ApplicationMaster),负责协调运行MapReduce作业的任务。它和MapReduce任务在容器中运行,这些容器由资源管理器分配并由节点管理器进行管理。
ResourceManager
是一个全局的资源管理器,负责整个系统的资源管理和分配。客户端把作业提交给RM(MR1.0是提交给jobtracker),获取新的作业ID。
总的来说,RM有以下作用:
1)处理客户端请求
2)启动或监控ApplicationMaster
3)监控NodeManager
4)资源的分配与调度
它主要由两个组件构成:调度器(Schedule)和应用程序管理器(Application Manager,ASM)
- 调度器(Scheduler):从本质上来说,定时调度器就是一种策略,或者说一种算法。当Client提交一个任务的时候,它会根据所需要的资源以及当前集群的资源状况进行分配。调度器分配一个容器,然后资源管理器在节点管理器(NodeManager)的管理下在容器中启动应用程序的master进程。注意,它只负责向应用程序分配资源,并不做监控以及应用程序的状态跟踪。
- 应用管理器(ApplicationManager):应用管理器就是负责管理Client用户提交的应用。上面不是说到调度器(Scheduler)不对用户提交的程序监控嘛,其实啊,监控应用的工作正是由应用管理器(ApplicationManager)完成的。
ApplicationMaster
每一个提交到集群的作业都会有一个与之对应的Application Master来负责应用程序的管理。他负责进行数据切分;为当前应用程序向ResourceManager去申请资源(也就是Container),并分配给具体的任务;与NodeManager通信,用来启停具体的任务,任务运行在Container中;而任务的监控和容错也是由Application Master来负责的。
从 YARN 角度讲,ApplicationMaster 是用户代码,因此存在潜在的安全问题。YARN 假设 ApplicationMaster 存在错误或者甚至是恶意的,因此将它们当作无特权的代码对待。
总的来说,AM有以下作用:
1)负责数据的切分
2)为应用程序申请资源并分配给内部的任务
3)任务的监控与容错
NodeManager
是在集群每个节点上运行的从属进程。它的主要工作是创建、监视和杀死容器。它为来自ResourceManager和ApplicationMaster的请求提供服务以创建容器,并向ResourceManager报告容器的状态。ResourceManager使用这些状态消息中包含的数据对请求做出调度决策。在非HA模式下,只存在ResourceManager单个实例。NodeManager管理抽象容器,这些容器代表着可供一个特定应用程序使用的针对每个节点的资源。YARN继续使用HDFS层,它的主要NameNode主要用于元数据服务,而DataNode用于分散在一个集群中的复制存储服务。
Container
Container 是 YARN 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当AM向RM申请资源时,RM为AM返回的资源便是用Container表示的。YARN会为每个任务分配一个Container,且该任务只能使用该Container中描述的资源。
Uber任务
在有些情况下,运行于Hadoop集群上的一些mapreduce作业本身的数据量并不是很大,如果此时的任务分片很多,那么为每个map任务或者reduce任务频繁创建Container,势必会增加Hadoop集群的资源消耗,并且因为创建分配Container本身的开销,还会增加这些任务的运行时延。如果能将这些小任务都放入少量的Container中执行,将会解决这些问题。好在Hadoop本身已经提供了这种功能,只需要我们理解其原理,并应用它。Uber运行模式就是解决此类问题的现成解决方案。
Uber运行模式对小作业进行优化,不会给每个任务分别申请分配Container资源,这些小任务将统一在一个Container中按照先执行map任务后执行reduce任务的顺序串行执行。那么什么样的任务,mapreduce框架会认为它是小任务呢?
- map任务的数量不大于mapreduce.job.ubertask.maxmaps参数(默认值是9)的值;
- reduce任务的数量不大于mapreduce.job.ubertask.maxreduces参数(默认值是1)的值;
- 输入文件大小不大于mapreduce.job.ubertask.maxbytes参数(默认为1个Block的字节大小)的值;
- map任务和reduce任务需要的资源量不能大于MRAppMaster(mapreduce作业的ApplicationMaster)可用的资源总量;也就是说yarn.app.mapreduce.am.resource.mb必须大于mapreduce.map.memory.mb和mapreduce.reduce.memory.mb以及yarn.app.mapreduce.am.resource.cpu-vcores必须大于mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores以启用ubertask。
- 参数mapreduce.job.ubertask.enable用来控制是否开启Uber运行模式,默认为false(不可用)。
任务分配(内存分配)
MR1.0的内存分配方式通过插槽管理任务执行,MR1.0中tasktracker有在集群配置时设置的固定数量的槽,每个任务在一个槽上运行。槽有最大内存分配限制,这对集群是固定的,导致当任务使用较少内存时无法充分利用内存(因为其他等待的任务不能使用这些未使用的内存)以及由于任务不能获取足够内存而导致作业失败。
在YARN中,资源分为更细的粒度,所以可以避免上述问题。具体而言,应用程序可以请求最小到最大限制范围的任意最小值倍数的内存容量。默认的内存分配容量是调度器特定的,对于容量调度器,它的默认值最小值是1024MB(由yarn.scheduler.capacity.minimum-allocation-mb设置),默认最大值是10240MB(由yarn.scheduler.capacity.maximum-allocation-mb设置)。因此,任务可以通过设置来请求1-10GB的任意1GB倍数的内存容量(调度器在需要的时候使用最接近的倍数)。
YARN在默认情况下,map和reduce任务都分配到1024MB的内存,但也可以通过mapreduce.map.memory.mb和mapreduce.reduce.memory.mb来设置。