@[TOC]node
Apache Hadoop YARN 是 apache Software Foundation Hadoop的子项目,为分离Hadoop2.0资源管理和计算组件而引入。YARN的诞生缘于存储于HDFS的数据须要更多的交互模式,不仅仅是MapReduce模式。Hadoop2.0 的YARN 架构提供了更多的处理框架,好比spark框架,再也不强迫使用MapReduce框架。
从hadoop2.0 的架构图能够看出,YARN承担着本来由MapReduce承担的资源管理的功能,同时将这部分的功能打包使得他们能够被新的数据处理引擎使用。这也同时简化了MapReduce的流程,使得MapReduce专一的将数据处理作到最好。使用YARN,能够用共同的资源管理,在Hadoop上跑不少应用程序。目前,不少机构已经开发基于YARN的应用程序。apache
YARN的架构仍是经典的主从(master/slave)结构,以下图所示。大致上看,YARN服务由一个ResourceManager(RM)和多个NodeManager(NM)构成,ResourceManager为主节点(master),NodeManager为从节点(slave)
在YARN体系结构中,全局ResourceManager做为主守护程序运行,该仲裁程序在各类竞争应用程序之间仲裁可用的群集资源。ResourceManager跟踪群集上可用的活动节点和资源的数量,并协调用户提交的应用程序应获取这些资源的时间和时间。ResourceManager是具备此信息的单个进程,所以它能够以共享,安全和多租户的方式进行分配(或者更确切地说,调度)决策(例如,根据应用程序优先级,队列容量,ACL,数据位置等)。
当用户提交应用程序时,将启动名为ApplicationMaster的轻量级进程实例,以协调应用程序中全部任务的执行。这包括监视任务,从新启动失败的任务,推测性地运行慢速任务以及计算应用程序计数器的总值。这些职责先前已分配给全部工做的单个JobTracker。ApplicationMaster和属于其应用程序的任务在NodeManagers控制的资源容器中运行。
ApplicationMaster能够在容器内运行任何类型的任务。例如,MapReduce ApplicationMaster请求容器启动map或reduce任务,而Giraph ApplicationMaster请求容器运行Giraph任务。您还能够实现运行特定任务的自定义ApplicationMaster,并以此方式建立一个闪亮的新分布式应用程序框架,该框架能够更改大数据世界。我鼓励您阅读Apache Twill,它旨在简化编写位于YARN之上的分布式应用程序。
一个能够运行任何分布式应用程序的集群 ResourceManager,NodeManager和容器不关心应用程序或任务的类型。全部特定于应用程序框架的代码都被简单地移动到其ApplicationMaster,以便YARN能够支持任何分布式框架,只要有人为它实现适当的ApplicationMaster。因为这种通用方法,运行许多不一样工做负载的Hadoop YARN集群的梦想成真。想象一下:数据中心内的单个Hadoop集群能够运行MapReduce,Giraph,Storm,Spark,Tez / Impala,MPI等。安全
核心组件: |
组件名 | 做用 |
---|---|---|
ResourceManager | 至关于这个Application的监护人和管理者,负责监控、管理这个Application的全部Attempt在cluster中各个节点上的具体运行,同时负责向YarnResourceManager申请资源、返还资源等; | |
ApplicationMaster | 至关于这个Application的监护人和管理者,负责监控、管理这个Application的全部Attempt在cluster中各个节点上的具体运行,同时负责向YarnResourceManager申请资源、返还资源等; | |
NodeManager | 是Slave上一个独立运行的进程,负责上报节点的状态(磁盘,内存,cpu等使用信息); | |
Container | 是yarn中分配资源的一个单位,包涵内存、CPU等等资源,YARN以Container为单位分配资源; |
RM是一个全局的资源管理器,集群只有一个,负责整个系统的资源管理和分配,包括处理客户端请求、启动/监控ApplicationMaster、监控 NodeManager、资源的分配与调度。它主要由两个组件构成:调度器(Scheduler)和应用程序管理器(Applications Manager,ASM)。
(1)调度器
调度器根据容量、队列等限制条件(如每一个队列分配必定的资源,最多执行必定数量的做业等),将系统中的资源分配给各个正在运行的应用程序。须要注意的是,该调度器是一个“纯调度器”,它从事任何与具体应用程序相关的工做,好比不负责监控或者跟踪应用的执行状态等,也不负责从新启动因应用执行失败或者硬件故障而产生的失败任务,这些均交由应用程序相关的ApplicationMaster完成。
调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象概念“资源容器”(ResourceContainer,简称Container)表示,Container是一个动态资源分配单位,它将内存、CPU、磁盘、网络等资源封装在一块儿,从而限定每一个任务使用的资源量。
(2)应用程序管理器
应用程序管理器主要负责管理整个系统中全部应用程序,接收job的提交请求,为应用分配第一个 Container 来运
行 ApplicationMaster,包括应用程序提交、与调度器协商资源以启动 ApplicationMaster、监控
ApplicationMaster 运行状态并在失败时从新启动它等。网络
管理 YARN 内运行的一个应用程序的每一个实例。关于 job 或应用的管理都是由 ApplicationMaster 进程负责的,Yarn 容许咱们觉得本身的应用开发 ApplicationMaster。
功能:
(1)数据切分;
(2)为应用程序申请资源并进一步分配给内部任务(TASK);
(3)任务监控与容错;
负责协调来自ResourceManager的资源,并经过NodeManager监视容易的执行和资源使用状况。Yarn 的动态性,就是来源于多个Application 的ApplicationMaster 动态地和 ResourceManager 进行沟通,不断地申请、释放、再申请、再释放资源的过程。架构
NodeManager 整个集群有多个,负责每一个节点上的资源和使用。
NodeManager 是一个 slave 服务:它负责接收 ResourceManager 的资源分配请求,分配具体的 Container 给应用。同时,它还负责监控并报告 Container 使用信息给 ResourceManager。经过和ResourceManager 配合,NodeManager 负责整个 Hadoop 集群中的资源分配工做。
功能:本节点上的资源使用状况和各个 Container 的运行状态(cpu和内存等资源)
(1)接收及处理来自 ResourceManager 的命令请求,分配 Container 给应用的某个任务;
(2)定时地向RM汇报以确保整个集群平稳运行,RM 经过收集每一个 NodeManager 的报告信息来追踪整个集群健康状态的,而 NodeManager 负责监控自身的健康状态;
(3)处理来自 ApplicationMaster 的请求;
(4)管理着所在节点每一个 Container 的生命周期;
(5)管理每一个节点上的日志;
(6)执行 Yarn 上面应用的一些额外的服务,好比 MapReduce 的 shuffle 过程;
当一个节点启动时,它会向 ResourceManager 进行注册并告知 ResourceManager 本身有多少资源可用。在运行期,经过 NodeManager 和 ResourceManager 协同工做,这些信息会不断被更新并保障整个集群发挥出最佳状态。NodeManager 只负责管理自身的 Container,它并不知道运行在它上面应用的信息。负责管理应用信息的组件是ApplicationMasterapp
Container 是 YARN 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当 AM 向RM 申请资源时,RM 为 AM 返回的资源即是用 Container 表示的。YARN 会为每一个任务分配一个 Container,且任务只能使用该 Container 中描述的资源。
Container 和集群节点的关系是:一个节点会运行多个 Container,但一个 Container 不会跨节点。任何一个 job或 application 必须运行在一个或多个 Container 中,在 Yarn 框架中,ResourceManager 只负责告诉ApplicationMaster 哪些 Containers 能够用,ApplicationMaster 还须要去找 NodeManager 请求分配具体的Container。
须要注意的是,Container 是一个动态资源划分单位,是根据应用程序的需求动态生成的。目前为止,YARN 仅支持 CPU 和内存两种资源,且使用了轻量级资源隔离机制 Cgroups 进行资源隔离。框架
Yarn的设计目标就是容许咱们的各类应用以共享、安全、多租户的形式使用整个集群。而且,为了保证集群资源调度和数据访问的高效性,Yarn还必须可以感知整个集群拓扑结构。
为了实现这些目标,ResourceManager的调度器Scheduler为应用程序的资源请求定义了一些灵活的协议,经过它就能够对运行在集群中的各个应用作更好的调度,所以,这就诞生了Resource Request和Container。一个应用先向ApplicationMaster发送一个知足本身需求的资源请求,而后ApplicationMaster把这个资源请求以
resource-request的形式发送给ResourceManager的Scheduler,Scheduler再在这个原始的resource-request中返回分配到的资源描述Container。每一个ResourceRequest可看作一个可序列化Java对象,包含的字段信息以下:分布式
<!-- - resource-name:资源名称,现阶段指的是资源所在的host和rack,后期可能还会支持虚拟机或者更复杂的网络结构 - priority:资源的优先级 - resource-requirement:资源的具体需求,现阶段指内存和cpu需求的数量 - number-of-containers:知足需求的Container的集合 --> <resource-name, priority, resource-requirement, number-of-containers>
做业历史服务,记录在yarn中调度的做业历史运行状况状况 , 经过mr-jobhistory-daemon.sh start historyserver命令在集群中的数据节点机器上不须要作任何配置,单独使用命令启动直接启动便可, 启动成功后会出现JobHistoryServer进程(使用jps命令查看,下面会有介绍) , 而且能够从19888端口进行查看日志详细信息
打开以下图界面,在下图中点击History,页面会进行一次跳转
点击History以后 跳转后的页面以下图,是空白的,这时由于咱们没有启动jobhistoryserver所致使的。 在三台机器上执行mr-jobhistory-daemon.sh start historyserver命令依次启动jobhistoryserver。在node1节点启动
此时咱们在三个节点把jobhistoryserver启动后,在此运行wordcount程序(记得启动前把输出目录删除掉)
点击History链接会跳转一个赞新的页面,在页面下方会看到TaskType中列举的map和reduce,Total表示这次运行的mapreduce程序执行所须要的map和reduce的任务数据.ide
用来写日志服务数据 , 通常来写与第三方结合的日志服务数据(好比spark等),从官网的介绍看,它是对jobhistoryserver功能的有效补充,jobhistoryserver只能对mapreduce类型的做业信息进行记录,除了jobhistoryserver可以进行对做业运行过程当中信息进行记录以外还有更细粒度的信息记录,好比任务在哪一个队列中运行,运行任务时设置的用户是哪一个用户。根据官网的解释jobhistoryserver只能记录mapreduce应用程序的记录,timelineserver功能更强大,但不是替代jobhistory二者是功能间的互补关系。oop
YARN 是如何工做的? YARN的基本理念是将JobTracker/TaskTracker 两大职能分割为如下几个实体:
1.一个全局的资源管理ResourceManager
Application在Yarn中的执行过程,整个执行过程能够总结为三步:
(1)应用程序提交
(2)启动应用的ApplicationMaster实例
(3)ApplicationMaster 实例管理应用程序的执行
具体过程:
(1)客户端程序向 ResourceManager 提交应用并请求一个 ApplicationMaster 实例;
(2)ResourceManager 找到一个能够运行一个 Container 的 NodeManager,并在这个 Container 中启动ApplicationMaster 实例;
(3)ApplicationMaster 向 ResourceManager 进行注册,注册以后客户端就能够查询 ResourceManager 得到本身 ApplicationMaster 的详细信息,之后就能够和本身的 ApplicationMaster 直接交互了(这个时候,客户端主动和 ApplicationMaster 交流,应用先向 ApplicationMaster 发送一个知足本身需求的资源请求);
(4)在日常的操做过程当中,ApplicationMaster 根据 resource-request协议 向 ResourceManager 发送 resource-request请求;
(5)当 Container 被成功分配后,ApplicationMaster 经过向 NodeManager 发送 container-launch-specification信息 来启动Container,container-launch-specification信息包含了可以让Container 和ApplicationMaster 交流所须要的资料;
(6)应用程序的代码以 task 形式在启动的 Container 中运行,并把运行的进度、状态等信息经过 application-specific协议 发送给ApplicationMaster;
(7)在应用程序运行期间,提交应用的客户端主动和 ApplicationMaster 交流得到应用的运行状态、进度更新等信息,交流协议也是 application-specific协议;
(8)一旦应用程序执行完成而且全部相关工做也已经完成,ApplicationMaster 向 ResourceManager 取消注册而后关闭,用到全部的 Container 也归还给系统。
(1)客户端提交hadoop jar
(2)找到main()方法中的job.waitForCompletition生成job对象,运行job对象的runjob()方法,与ResourceManager通讯,
返回ResourceManager分配一个ID号(applicationid),需不须要输出,若是须要输出,判断输出是否存在,若是不存在问题,在看输入,根据hdfs获得输入获得分片信息,根据分片信息获得map个数,将这些信息回传给客户端Job
(3)把Job所须要的资源,例如Jar包,配置文件,split分片信息,上传到hdfs中去
(4)Job对象告知与ResourceManager提交应用
(5)ResourceManager寻找合适的节点开启container容器(本质上是一个JVM虚拟机)
(6)在container中启动一个applicationMaster,初始化Job,生成一个薄记对象(就是一个记事本),记录map、reduce的状态。把job全部资源上传到hdfs中,包括jar包,配置文件,split信息
(7)applicationMaster向ResourceManager申请资源,返回资源信息(包括node节点地址,cpu信息,内存占比,IO信息)
(8)applicationMaster收到信息以后,和NodeManager通讯,传递资源信息
(9)开启YarnChild进程,从hdfs中得到Job详细信息(包括Jar包,配置文件信息)
(一)Job初始化:一、当resourceManager收到了submitApplication()方法的调用通知后,scheduler开始分配container,随之ResouceManager发送applicationMaster进程,告知每一个nodeManager管理器。 二、由applicationMaster决定如何运行tasks,若是job数据量比较小,applicationMaster便选择将tasks运行在一个JVM中。那么如何判别这个job是大是小呢?当一个job的mappers数量小于10个,只有一个reducer或者读取的文件大小要小于一个HDFS block时,(可经过修改配置项mapreduce.job.ubertask.maxmaps,mapreduce.job.ubertask.maxreduces以及mapreduce.job.ubertask.maxbytes 进行调整) 三、在运行tasks以前,applicationMaster将会调用setupJob()方法,随之建立output的输出路径(这就可以解释,无论你的mapreduce一开始是否报错,输出路径都会建立)。
(二)Task 任务分配:一、接下来applicationMaster向ResourceManager请求containers用于执行map与reduce的tasks(step 8),这里map task的优先级要高于reduce task,当全部的map tasks结束后,随之进行sort(这里是shuffle过程后面再说),最后进行reduce task的开始。(这里有一点,当map tasks执行了百分之5%的时候,将会请求reduce,具体下面再总结) 二、运行tasks的是须要消耗内存与CPU资源的,默认状况下,map和reduce的task资源分配为1024MB与一个核,(可修改运行的最小与最大参数配置,mapreduce.map.memory.mb,mapreduce.reduce.memory.mb,mapreduce.map.cpu.vcores,mapreduce.reduce.reduce.cpu.vcores.)
(三)运行进度与状态更新 一、MapReduce是一个较长运行时间的批处理过程,能够是一小时、
几小时甚至几天,那么Job的运行状态监控就很是重要。每一个job以及每一个task都有一个包含
job(running,successfully completed,failed)的状态,以及value的计数器,状态信息及描述信息(描述信息通常都是在代码中加的打印信息),那么,这些信息是如何与客户端进行通讯的呢? 二、当一个task开始执行,它将会保持运行记录,记录task完成的比例,对于map的任务,将会记录其运行的百分比,对于reduce来讲可能复杂点,但系统依旧会估计reduce的完成比例。当一个map或reduce任务执行时,子进程会持续每三秒钟与applicationMaster进行交互。
<!-- $HADOOP_HOME/etc/hadoop/mapred-site.xml --> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> <!-- $HADOOP_HOME/etc/hadoop/yarn-site.xml --> <configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>
启动 ResourceManager 和 NodeManager (如下分别简称RM、NM)
#主节点运行命令 $HADOOP_HOME/sbin/start-yarn.sh #主节点运行命令 $HADOOP_HOME/sbin/stop-yarn.sh 若RM没有启动起来,能够单独启动
若RM没有启动起来,能够单独启动
#若RM没有启动,在主节点运行命令 $HADOOP_HOME/sbin/yarn-daemon.sh start resouremanager #相反,可单独关闭 $HADOOP_HOME/sbin/yarn-daemon.sh stop resouremanager
若NM没有启动起来,能够单独启动
#若NM没有启动,在相应节点运行命令 $HADOOP_HOME/sbin/yarn-daemon.sh start nodemanager #相反,可单独关闭 $HADOOP_HOME/sbin/yarn-daemon.sh stop nodemanager
#1.查看正在运行的任务 yarn application -list #2.杀掉正在运行任务 yarn application -kill 任务id #3.查看节点列表 yarn node -list #4.查看节点情况 TODO yarn node -status node3:40652 #5.查看yarn依赖jar的环境变量 yarn classpath
在Yarn中有三种调度器能够选择:FIFO Scheduler ,Capacity Scheduler,FairS cheduler
FIFO Scheduler把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,待最头上的应用需求知足后再给下一个分配,以此类推。FIFO Scheduler是最简单也是最容易理解的调度器,也不须要任何配置,但它并不适用于共享集群。大的应用可能会占用全部集群资源,这就致使其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或FairScheduler,这两个调度器都容许大任务和小任务在提交的同时得到必定的系统资源。下面“Yarn调度器对比图”展现了这几个调度器的区别,从图中能够看出,在FIFO 调度器中
而对于Capacity调度器,有一个专门的队列用来运行小任务,可是为小任务专门设置一个队列会预先占用必定的集
群资源,这就致使大任务的执行时间会落后于使用FIFO调度器时的时间。
如何配置容量调度器
队列层级结构以下:
root
├── prod
└── dev
├── spark
└── hdp
HADOOP_HOME/etc/hadoop/中创建一个新的capacity-scheduler.xml;内容以下:
<?xml version="1.0" encoding="utf-8"?> <configuration> <property> <name>yarn.scheduler.capacity.root.queues</name> <value>prod,dev</value> </property> <property> <name>yarn.scheduler.capacity.root.dev.queues</name> <value>hdp,spark</value> </property> <property> <name>yarn.scheduler.capacity.root.prod.capacity</name> <value>40</value> </property> <property> <name>yarn.scheduler.capacity.root.dev.capacity</name> <value>60</value> </property> <property> <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name> <value>75</value> </property> <property> <name>yarn.scheduler.capacity.root.dev.hdp.capacity</name> <value>50</value> </property> <property> <name>yarn.scheduler.capacity.root.dev.spark.capacity</name> <value>50</value> </property> </configuration>
将应用放置在哪一个队列中,取决于应用自己。
例如MR,能够经过设置属性mapreduce.job.queuename指定相应队列。以WordCount为例,以下,若是指定的队列不存在,则发生错误。若是不指定,默认使用"default"队列,以下图
在Fair调度器中,咱们不须要预先占用必定的系统资源,Fair调度器会为全部运行的job动态的调整系统资源。当第一个大job提交时,只有这一个job在运行,此时它得到了全部集群资源;当第二个小任务提交后,Fair调度器会分配一半资源给这个小任务,让这两个任务公平的共享集群资源。须要注意的是,在下图Fair调度器中,从第二个任务提交到得到资源会有必定的延迟,由于它须要等待第一个任务释放占用的Container。小任务执行完成以后也会释放本身占用的资源,大任务又得到了所有的系统资源。最终的效果就是Fair调度器即获得了高的资源利用率又能保证小任务及时完成.