yarn资源调度器
Yarn基础架构
- YARN主要由Resourcemanager、Nodemanager、ApplicationMaster和Contatiner等组件构成。
作业提交全过(面试题)
- 作业提交
- 第一步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业
- 第二步:Client向RM申请一个作业id。
- 第三步:RM给Client返回该job资源提交路径和作业id。
- 第四步:Client提交jar包、切片信息和配置文件到指定的资源提交路径
- 第五步:Client提交完资源后,向RM申请运行MrAppMaster
- 作业初始化
- 第六步:当RM收到Client的请求后,将该job添加到容量调度器中。
- 第七步:某一个空闲的NM领取到该job
- 第八步:该NM创建Container,并产生MRAppMaster
- 第九步:下载Client提交的资源到本地
- 任务分配
- 第十步:MrAppMaster向RM申请运行多个MapTask任务资源
- 第十一步:RM将运行MapTask任务分配给另外两个NodeManager,另外两个NodeManager分别领取任务并创建容器。
- 任务运行
- 第十二步:MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTask,MapTask对数据分区排序。
- 第十三步:MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。
- 第十四步:ReduceTask向MapTask获取相应的分区的数据
- 第十五步:程序运行完毕后,MR会向RM申请注销自己
- 进度和状态更新
- YARN中的任务将其进度和状态(包括counter)返回给应用管理器,客户端每秒(通过mapreduce.client.progressmonitor.pollinterval设置)向应用管理器请求进度更新,展示给用户。
- 作业完成
- 除了向应用管理器请求作业进度外,客户端每5秒都会通过调用waitForCompletion()来检查作业是否完成。时间间隔可以通过mapreduce.client.completion.pollinterval来设置。作业完成之后,应用管理器和Container会清理工作状态。作用和的信息会被作业历史服务器存储以备之后用户检查。
yarn调度器和调度算法
- 目前,Hadoop作业调度器主要有三种,FIFO、容量(Capacity Scheduler)和公平(Fair Scheduler)。Apache Hadoop3.1.3默认的调度器是Capacity Scheduler。
- CDH框架(Cloudra's Distribution Apache Of Hadoop)默认的调度器是Fair Scheduler
- 具体设置详见:yarn-default文件
<property>
<description>The class to use as the resource scheduler.</description>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
先进先出调度器(FIFO)
- FIFO调度器(First In First Out): 单队列,根据提交作业的先后顺序,先来先服务。
- 优点: 简单易懂
- 缺点: 不支持多队列,生产环境很少使用
容量调度器(Capacity Scheduler)
- Capacity Scheduler是Yahoo开发的多用户调度器
- 多队列: 每个队列配置一定的资源,每个队列采用FIFO调度策略。
- 容量保证:管理员可为每个队列设置资源最低保证和资源使用上限。
- 灵活性:如果一个队列资源有剩余,可暂时共享给那些需要资源的队列,而一旦队列有了新的应用程序提交,则其他队列借调的资源会归还给该队列。
- 多租户:(1)支持多用户共享集群和多应用程序同时运行。(2)为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源进行限制。
- 队列资源分配:从root开始,使用深度优先搜索算法,优先选择资源占用率低的队列进行分配资源。
- 作业资源分配:默认按照提交作业的优先级和提交时间顺序分配资源。
- 容器资源分配:按照容器的优先级进行分配资源,如果优先级相同,按照数据本地性原则。(1)任务和数据在同一个节点(2)任务和数据在同一个机架(3)任务和数据不在同一个节点也不在同一个机架。
公平调度器
- Fair Schedulere是FaceBook开发的多用户调度器
- 同对垒所用任务共享资源,在时间尺度上获得公平的资源
- 核心调度策略不同: (1) 容量调度: 优先选择资源利用率低的队列。 (2) 公平调度: 优先选择对资源缺额比例大的
- 每个队列可以单独设置资源分配方式: (1) 容量调度: FIFO、DRF (2) 公平调度: FIFO、FAIR、DRF
- 某一时刻一个作业应获得的资源和实际获取的资源差距叫“缺额”
- 调度器会优先为缺额大的作业分配资源
- Fair策略
- 资源分配步骤:选择队列,选择作业,选择容器
-
- 分别计算比对象的(实际最小资源份额,是否饥饿,资源分配比,资源使用权重比)
-
- 判断两种比较对象的饥饿状态
-
- 其中一个饥饿:饥饿优先
-
- 都饥饿:资源分配比小者优先,若相同,则按照提交时间顺序
-
- 都不饥饿:资源使用权重比小者优先,若相同,则按照提交时间顺序
- 实际最小份额: mindShare = Min(资源需求量,配置的最小资源)
- 是否饥饿:isNeedy = 资源使用量 < mindShare(实际最小资源份额)
- 资源分配比:minShareRatio = 资源使用量 / Max(mindShare, 1)
- 资源使用权重比:useToWeightRatio = 资源使用量 / 权重
Yarn常用命令
Yarn application 查看任务
# 1. 列出所有Application
yarn application -list
# 2. 根据Application状态过滤: yarn application -list appStates (所有状态:ALL, NEW,
NEW_SAVING, SUBMITTED, ACCEPTED, RUNNING, FINISHED, FAILED, KILLED)
yarn application -list -appStates FINISHED
# 3. Kill掉Application
yarn application -kill application_1691032363493_0002
Yarn logs查看日志
# 1. 查询Application日志
yarn logs -applicationId <ApplicationId>
# 2. 查询Container日志
yarn logs -applicationId <ApplicationId> -containerId <ContainerId>
Yarn applicationattempt 查看尝试运行的任务
# 1.列出Application尝试的列表
yarn applicationattempt -list <applicationId>
# 2. 打印ApplicationAttemp状态
yarn applicationattempt -status <ApplicationAttemptId>
Yarn container查看容器
# 1. 列出所有容器
yarn container -list <ApplicationAttemptId>
# 打印Container状态
yarn container -states <ContainerId>
# 只有在任务跑的途中才能看到container的状态
Yarn node查看阶段状态
# 列出所有节点
yarn node -list -all
Yarn rmadmin更新配置
# 加载队列配置,重读配置文件
yarn rmadmin -refreshQueues
Yarn queue查看队列
# 打印队列信息
yarn queue -status <QueueName>
# 例
yarn queue -status default
Yarn生产环境核心参数配置
ResourceManager相关
# 配置调度器,默认容量调度器,大厂并发度较高,用容量,中小厂并发度小,用公平
yarn.resouecemanager.scheuler.class
# ResourceManager处理调度器请求的线程数量,**默认50**
yarn.resourcemanager.scheduler.client.thread-count
NodeManager相关
# 是否让yarn自己检测硬件进行配置,**默认false**
yarn.nodemanager.resource.detect-hardware-capabilities
# 是否将虚拟核数当做cpu核数, 默认false
yarn.nodemanager.resource.count-logical-processor-as-core
# 虚拟核数和物理核数乘数,如四核八线程,该参数就位2, **默认1.0**
yarn.nodemanager.resource.pcores-vcores-multiplier
# NodeManager使用内存, 默认8G
yarn.nodemanager.resource.memory-mb
# 为系统保留多少内存, 与以上参数,这两个配置一个就行
yarn.nodemanager.resource.system-reserved-memory-mb
# NodeManager使用CPU核数,默认8个, 超过单机核数会崩溃
yarn.nodemanager.resource.cpu-vcores
# 是否开启物理内存检查限制container,默认打开, 使用内存超过实际内存会预警
yarn.nodemanager.vmem-check-enabled
# 虚拟内存物理内存比例,默认2.1
yarn.nodemanager.vmem-pmem-ratio
Container相关
# 容器最小内存, 默认1G
yarn.scheduler.minimum-allocation-mb
# 容器最大内存,默认8G, 超过Nodemanage的使用内存会崩溃
yarn.scheduler.maximum-allocation-mb
# 容器最小cpu核数, 默认1个
yarn.scheduler.minimum-allocation-vcores
# 容器最大CPU核数,默认4个
yarn.scheduler.maximum-allocation-csores
配置多队列的容量调度器
- 在capacity-scheduler.xml文件中配置如下
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default,hive</value>
<description>
The queues at the this level (root is the root queue).
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>40</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>60</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.capacity</name>
<value>60</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.user-limit-factor</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.maximum-capacity</name>
<value>80</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.state</name>
<value>RUNNING</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.acl_submit_applications</name>
<value>*</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.acl_administer_queue</name>
<value>*</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.acl_application_max_priority</name>
<value>*</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.maximum-application-lifetime</name>
<value>-1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.hive.default-application-lifetime</name>
<value>-1</value>
</property>
# -D表示运行时改变参数值
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount -D
mapreduce.job.queuename=hive /input /output
# 在java程序中修改相应的配置
conf.set("mapreduce.job.queuename", "hive");
任务优先级
- yarn默认所有任务优先级为0,若想使用任务的优先级功能,需开放限制。
# 修改yarn-site.xml文件,增加以下参数
<property>
<name>yarn.cluster.max-application-priority</name>
<value>5</value>
</property>
# 分发配置,重启yarn
# 提交高优先级作业
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar
pi -D mapreduce.job.priority=5 5 2000000
# 通过以下命令修改正在执行的任务的优先级
yarn application -appID application_1611133087930_0009 -updatePriority 5
公平调度器案例
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
<description>配置使用公平调度器</description>
</property>
<property>
<name>yarn.scheduler.fair.allocation.file</name>
<value>/usr/local/hadoop/hadoop-3.1.3/etc/hadoop/fair-scheduler.xml</value>
<description>指明公平调度器队列分配配置文件</description>
</property>
<property>
<name>yarn.scheduler.fair.preemption</name>
<value>false</value>
<description>禁止队列间资源抢占</description>
</property>
- 新建fair-scheduler.xml,写入以下内容
<?xml version="1.0"?>
<allocations>
<queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>
<queueMaxResourcesDefault>4096mb,4vcores</queueMaxResourcesDefault>
<queue name="test">
<minResources>2048mb,2vcores</minResources>
<maxResources>4096mb,4vcores</maxResources>
<maxRunningApps>4</maxRunningApps>
<maxAMShare>0.5</maxAMShare>
<weight>1.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
</queue>
<queue name="atguigu" type="parent">
<minResources>2048mb,2vcores</minResources>
<maxResources>4096mb,4vcores</maxResources>
<maxRunningApps>4</maxRunningApps>
<maxAMShare>0.5</maxAMShare>
<weight>1.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
</queue>
<queuePlacementPolicy>
<rule name="specified" create="false"/>
<rule name="nestedUserQueue" create="true">
<rule name="primaryGroup" create="false"/>
</rule>
<rule name="reject" />
</queuePlacementPolicy>
</allocations>
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi -Dmapreduce.job.queuename=root.test 1 1
Yarn的Tool接口案例
- 需求:希望能够在使用命令行运行自己编写的程序时,能够动态传参。
- 实现: 使用yarn的Tool接口,ToolRunner类和Tool接口是Hadoop MapReduce框架的一部分,主要用于在Hadoop集群上运行MapReduce作业
- Tool接口:是MapReduce作业的接口,定义了一个run方法,负责运行整个MapReduce作业。
- ToolRunner类:是一个辅助类,用于运行实现了Tool接口的MapReduce作业。其中包含GenericOptionsParser对象,其getRemainingArgs()方法可获取除通用选项外的剩余命令行参数(用户自定义的选项)。
public class WordCount implements Tool {
private Configuration conf;
@Override
public int run(String[] strings) throws Exception {
Job job = Job.getInstance(conf);
job.setJarByClass(WordCountDriver.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.setInputPaths(job, new Path(strings[0]));
FileOutputFormat.setOutputPath(job, new Path(strings[1]));
return job.waitForCompletion(true) ? 0 : 1;
}
@Override
public void setConf(Configuration configuration) {
conf = configuration;
}
@Override
public Configuration getConf() {
return conf;
}
public static class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
Text k = new Text();
IntWritable v = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
String[] split = value.toString().split("\t");
for (String s : split) {
k.set(s);
context.write(k, v);
}
}
}
public static class WordCountReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
IntWritable v = new IntWritable();
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
v.set(sum);
context.write(key, v);
}
}
}
- 创建WordCountDriver类,使用ToolRunner来运行Mapreduce程序
public class WordCountDriver {
private static Tool tool;
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
switch (args[0]) {
case "wordcount":
tool = new WordCount();
break;
default:
throw new RuntimeException("no such tool " + args[0]);
}
String[] strings = Arrays.copyOfRange(args, 1, args.length);
int run = ToolRunner.run(conf, tool, strings);
System.exit(run);
}
}
- jar包上传集群,并使用命令行运行, 自定义参数指定作业提交的队列
yarn jar wc.jar com.atguigu.yarn.WordCountDriver wordcount -Dmapreduce.job.queuename=root.test /input /output9
- hadoop jar与 yarn jar的区别
- hadoop jar: 按mr或yarn运行job,取决于是否配置yarn,资源调度模式可能是local,也可能是yarn
- yarn jar: 按照yarn运行job,资源调度是yarn
Yarn重点总结
- Yarn工作机制(面试重点)
- Yarn的调度器
- FIFO/容量/公平
- apache 默认调度器 容量, CDH默认调度器 公平
- 公平/容量默认一个default队列,需要创建多队列
- 中小企业,按作业类型创建队列: hive spark flink mr
- 中大企业,按照业务模块创建队列:登录/注册/购物车/营销
- 好处:解耦 降低风险, 11.11 6.18等特殊时期,可对不不同队列降级处理
- 每个调度器的特点:
- 相同点:支持多队列,可以借资源,支持对用户
- 不同点:1)容量调度器:优先满足先进来的任务执行 2)公平调度器:在队列里面的任务公平享有队列资源
- 生产环境怎么选:
- 中小企业:对并发度要求不高,选择容量
- 中大企业:对并发度要求较高,选择公平
- 开发需要重点掌握:
- 队列运行原理
- Yarn常用命令
- 核心参数配置
- 配置容量调度器和公平调度器
- tool接口使用