Yarn 概述、调度器与调度算法
YARN
概述
Yet Another Resource Negotiator,资源(内存、cpu等)管理器,相当于一个分布式操作系统平台,MapReduce等运算程序相当于运行于OS上的应用程序
Hadoop1.0中,jobTracker的任务过多(接收任务、资源调度、监控TaskTracker运行情况),虽然实现简单但容易产生单点故障问题
ResourceManager:整个集群的资源管理(单节点的cpu*节点数、单节点的内存*节点数)
- 处理客户端请求,监控NodeManager,启动ApplicationMaster
- 一个集群有且只有一个RM,包含两个主要组件:定时调用器(Scheduler)、应用管理器(ApplicationManager)
- 调度器:一种策略或算法,Client提交一个任务后,根据所需资源和集群当前资源状况进行分配——只负责向应用程序分配资源,不监控或跟踪应用程序的状态
- 应用管理器(AM):管理单个任务的运行,监控、跟踪状态
NodeManager:每个节点上运行的资源和任务管理器
- NodeManager是ResourceManager在每台机器的上代理
- 管理容器,监控容器的资源使用情况(cpu,内存,磁盘,网络等),向ResourceManager/Scheduler发送资源的使用报告,接收并处理来自AM的Container启动/停止等各种请求
ApplicationMaster:
- Client提交一个Application,就新建一个ApplicationMaster
- ApplicationMaster向ResourceManager申请容器资源,获得资源后将Application发送到容器上启动、分布式计算
数据太多难以移动,因此将容易移动的应用程序发布到各个节点进行计算
Container:任务运行的环境,Container封装了任务运行所需的资源——可以跨节点;由NodeManager启动和管理,并被它监控;被ResourceManager调度
全局组件: RM(Scheduler,ApplicationManager)、NM
Job独有组件:ApplicationMaster、Container
提交一个程序的流程:
- Client向Yarn提交Application(假设是一个MapReduce任务)
- RM的ApplicationManager向NodeManager通信,为Application分配一个运行Application对应ApplicationMaster的容器
- ApplicationMaster向RM注册并启动后,计算应用完成所需要的资源,拆分Application为多个task(task需要运行在一个或多个容器中),向RM申请需要的资源(容器),定时向RM发送心跳
- 申请容器后,ApplicationMaster与容器对应的VM通信,将作业分发到对应的NM的容器运行——对于一个MapReduce任务,容器中运行的可能是Map任务,可能是Reduce任务
- 容器中运行的任务向ApplicationMaster发送心跳。程序运行完成,ApplicationMaster向RM注销并释放容器的资源
运行一个mapreduce程序的流程:(假设有3个服务器)
作业提交
- Client调用方法job.waitForCompletion,将一个MapReduce job提交给集群
- Client向RM申请一个job id
- RM返回job的资源提交路径和job id给Client
- Client提交jar包、切片信息、配置文件到指定的提交路径
- Client提交完资源,向RM申请运行MrAppMaster(MapReduce对ApplicationMaster的实现)
作业初始化
- RM收到Client的请求,将job添加到容量调度器
- 某个空闲的NM领取该Job
- NM创建Container,产生MRAppmaster,下载Client提交的资源到NM本地
任务分配
- MrAppMaster向RM申请运行多个MapTask的资源
- RM将MapTask分配给另外两个NM,另两个 NM领取任务并创建容器
任务运行
- MR向两个接收到任务的NM发送程序启动脚本,它们分别启动MapTask
- MrAppMaster等待所有MapTask运行完毕,向RM申请容器,运行ReduceTask
- 程序运行完毕,MR向RM申请注销
进度和状态更新:YARN中的任务将其进度和状态返回应用管理器,Client每秒(
mapreduce.client.progressmonitor.pollinterval
参数设置)向应用管理器请求进度更新, 展示给用户作业完成
- Client每5秒调用waitForCompletion()(
mapreduce.client.completion.pollinterval
参数)检查作业是否完成 - 作业完成后,应用管理器和Container清理工作状态,作业信息被作业历史服务器存储,以备核查
- Client每5秒调用waitForCompletion()(
关键参数
- RM相关
yarn.resourcemanager.scheduler.class
:调度器,默认为容量调度器yarn.resourcemanager.scheduler.client.thread-count
:RM处理调度器请求的线程数,默认50
- NM相关
yarn.nodemanager.resource.detect-hardware-capabilities
:yarn自己检测硬件进行配置,默认为falseyarn.nodemanager.resource.count-logical-processors-as-cores
:虚拟核数当作cpu核数,默认falseyarn.nodemanager.resource.pcores-vcores-multiplier
:虚拟核数和物理核数乘数。4核8线程则为2,默认1.0yarn.nodemanager.resource.pcores-vcores-multiplier
:NM使用内存,默认8Gyarn.nodemanager.resource.system-reserved-memory-mb
:NM为系统保留多少内存yarn.nodemanager.resource.cpu-vcores
:NM使用CPU核数,默认8个yarn.nodemanager.pmem-check-enabled
:是否开启物理内存检查限制container,默认打开yarn.nodemanager.vmem-check-enabled
:是否开启虚拟内存检查限制container,默认打开yarn.nodemanager.vmem-pmem-ratio
:虚拟内存物理内存比例
- Container相关
yarn.scheduler.minimum-allocation-mb
:容器最小内存,默认1Gyarn.scheduler.maximum-allocation-mb
:容器最大内存,默认8Gyarn.scheduler.minimum-allocation-vcores
:容器最小CPU核数,默认1个yarn.scheduler.maximum-allocation-vcores
:容器最大CPU核数,默认4个
- RM相关
Yarn调度器和调度算法
- 主要有三种:
- FIFO
- 容量(Capacity Scheduler)
- 公平(Fair Scheduler)
- Hadoop默认资源调度器为Capacity Scheduler
- CDH默认调度器为Fair Scheduler
FIFO调度器
- 单队列,YARN集群中所有的资源全部调集过来,分配给当前任务,根据提交作业的先后顺序服务(不支持多队列,生产环境很少使用)
容量调度器
每个队列可以配置一定资源,队列采用FIFO调度
管理员为每个队列设置资源使用下限和上限
一个队列中的资源有剩余,则可暂时共享给其他队列,如果该队列有新的提交任务,则回收资源
支持多用户、多作业同时进行
限定同一用户提交的作业所占资源,以防止一个用户独占队列所有资源(上图ss、cls为用户)
资源分配算法:
- 假设队列A有20%资源,队列B有50%资源,队列C有30%资源,队列C下有两个子队列ss、和cls,分别占据15%资源
- 队列资源分配:深度优先算法,优先选择资源占用率最低的队列(此时优先选择队列A)
- 作业资源分配:默认按照作业的优先级和提交时间顺序分配资源(此时如果作业1的优先级高,则先分配作业1的资源)
- 容器分配:
- 按容器优先级分配资源(这里有三个容器,根据优先级分配任务)
- 如果优先级相同,按数据本地性原则
- 任务和数据在同一节点
- 任务和数据在同一机架
- 任务和数据不在同一节点、同一机架
相关参数的配置:
(1)
capacity
:队列的资源容量(百分比),所有队列的容量之和应小于100(2)
maximum-capacity
:队列的资源使用上限(百分比)(3)
user-limit-factor
:每个用户最多可使用的资源量(百分比)。假设值为30,则每个用户使用的资源量不能超过该队列容量的30%(4)
maximum-applications
:集群或者队列中同时处于等待和运行状态的应用程序数目上限——超过该上限,后续提交的任务将被拒绝,默认值为 10000。所有队列的数目上限可通过参数yarn.scheduler.capacity.maximum-applications
设置,单个队列可通过参数yarn.scheduler.capacity.<queue-path>.maximum-applications
设置(5)
maximum-am-resource-percent
:集群中用于运行应用程序ApplicationMaster的资源比例上限(6)
state
:状态可以为STOPPED或者 RUNNING,如果一个队列处于STOPPED状态,用户不能将任务提交到该队列或者它的子队列。如果ROOT队列处于STOPPED状态,用户不能向集群中提交任务(7)
acl_submit_applications
:限定哪些Linux用户/用户组可向给定队列提交应用程序——如果一个用户可以向某个队列提交应用程序,则它可以向所有子队列提交应用程序。用户之间或用户组之间用“,”分割,用户和用户组之间用空格分割,如user1, user2 group1, group2
(8)
acl_administer_queue
:为队列指定一个管理员,管理员可控制该队列的所有应用程序,如杀死任意一个应用程序等
公平调度器
异同:
- 相同点:
- 支持多队列
- 可设置队列的资源上下限
- 队列资源剩余,可共享给其他队列
- 限定同一用户提交作业所占资源
- 不同点:
- 核心调度策略:
- 容量:资源利用率低的队列优先
- 公平:资源的缺额比例大的队列优先
- 每个队列单独设置资源分配方式
- 容量:FIFO、DRF
- 公平:FIFIO、FAIR、DRF
- 核心调度策略:
- 相同点:
缺额:时间尺度上,所有作业获得公平的资源。某一时刻一个作业应获资源和实际获取资源的差距为缺额
资源分配方式:
- FIFO:若每个队列资源分配策略为FIFO,则公平调度器==容量调度器
- Fair:整个时间线上,所有Job平均获取资源。默认情况下,调度器只是对内存资源做公平的调度和分配——集群中只有一个任务在运行时,此任务占用整个集群的资源,当其他的任务提交,第一个任务缓慢释放资源,分配给新的Job,每个job最终能获取几乎一样多的资源
- DRF(Dominant Resource Fairness):
- 以上资源是单一标准,例如只考虑内存(Yarn默认)
- 假设集群有100CPU和10T内存,应用A需要(2 CPU,300GB),应用B需要(6CP,100GB), 则两个应用分别需要A(2%CPU, 3%内存)和B(6%CPU, 1%内存)——A是内存主导,B是CPU主导,此时DRF策略对不同应用进行不同资源(CPU和内存)做不同比例的限制
相关参数配置
(1)
yarn.scheduler.fair.allocation.file
: “allocation”文件的位置。“allocation”文件用来描述queue以及它们的属性的配置文件。这个文件必须为格式严格的xml文件。如果为相对路径,那么将会在classpath下查找此文件(conf目录下)。默认值为“fair-scheduler.xml”(2)
yarn.scheduler.fair.user-as-default-queue
:是否将与allocation有关的username作为默认的queue name,当queue name没有指定的时候。默认值为true(3)
yarn.scheduler.fair.preemption
:是否使用“preemption”(优先权,抢占),默认为fasle(4)
yarn.scheduler.fair.assignmultiple
:是否在允许在一个心跳中,发送多个container分配信息。默认值为false。(5)
yarn.scheduler.fair.max.assign
:如果assignmultuple为true,在一次心跳中,最多发送分配container的个数。默认为-1,无限制(6)
yarn.scheduler.fair.sizebaseweight
:是否将application的大小(Job的个数)作为权重。默认为false,如果为true,复杂的application将获取更多的资源
常用命令
- 查看任务
- 列出所有Application:
yarn application -list
- 根据Application状态过滤:
yarn application -list -appStates 状态
(状态包括ALL、NEW、 NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED) - Kill任务:
yarn application -kill application_1612577921195_0001
(最后的参数为Application-Id)
- 列出所有Application:
- 查看日志:
- 查询Application日志:
yarn logs -applicationId <ApplicationId>
- 查询Container日志:
yarn logs -applicationId <ApplicationId> -containerId <ContainerId>
- 查询Application日志:
- 查看尝试运行的任务:
- 所有尝试运行的任务:
yarn applicationattempt -list <ApplicationId>
- 查看某个任务状态:
yarn applicationattempt -status <ApplicationAttemptId>
- 所有尝试运行的任务:
- 查看容器:
- 所有容器:
yarn container -list <ApplicationAttemptId>
- 查看容器状态:
yarn container -status <ContainerId>
- 所有容器:
- 查看节点状态:
yarn node -list -all
- 查看队列信息:
yarn queue -status <QueueName>