当前位置 博文首页 > Shockang的博客:YARN 中有哪些调度器?
本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系
试想一下,你现在所在的公司有一个hadoop的集群。但是A项目组经常做一些定时的BI报表,B项目组则经常使用一些软件做一些临时需求。那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这两个任务呢?
是先执行A的任务,再执行B的任务,还是同时跑两个?
如果你存在上述的困惑,可以多了解一些yarn的资源调度器。
在Yarn框架中,调度器是一块很重要的内容。有了合适的调度规则,就可以保证多个应用可以在同一时间有条不紊的工作。
最原始的调度规则就是FIFO,即按照用户提交任务的时间来决定哪个任务先执行,先提交的先执行。但是这样很可能一个大任务独占资源,其他的资源需要不断的等待。也可能一堆小任务占用资源,大任务一直无法得到适当的资源,造成饥饿。所以FIFO虽然很简单,但是并不能满足我们的需求。
理想情况下,yarn应用发出的资源请求应该立刻给予满足。然而现实中的资源有限,在一个繁忙的集群上,一个应用经常需要等待才能得到所需的资源。yarn调度器的工作就是根据既定的策略为应用分配资源。调度通常是一个难题,并且没有一个所谓的“最好”的策略,这也是为什么yarn提供了多重调度器和可配置策略供我们选择的原因。
在Yarn中有三种调度器可以选择:FIFO Scheduler ,Capacity Scheduler,FairS cheduler
FIFO Scheduler把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,待最头上的应用需求满足后再给下一个分配,以此类推。
FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能会占用所有集群资源,这就导致其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或Fair Scheduler,这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。
下面“Yarn调度器对比图”展示了这几个调度器的区别,从图中可以看出,在FIFO 调度器中,小任务会被大任务阻塞。
默认使用容量调度器
而对于Capacity调度器,有一个专门的队列用来运行小任务,但是为小任务专门设置一个队列会预先占用一定的集群资源,这就导致大任务的执行时间会落后于使用FIFO调度器时的时间。
队列层级结构如下:
root
├── prod
└── dev
├── spark
└── hdp
主节点上,将$HADOOP_HOME/etc/hadoop/中的对应capacity-scheduler.xml配置文件备份到其它目录
若hadoop集群启动,关闭hadoop集群
在目录$HADOOP_HOME/etc/hadoop/中建立一个新的capacity-scheduler.xml;内容如下。
将此xml文件,远程拷贝到相同目录下
重启hadoop集群
<?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"队列,如下图
程序打包,提交集群运行
[hadoop@node-01 Desktop]$ hadoop jar com.shockang.hadoop-1.0-SNAPSHOT.jar com.shockang.hadoop.scheduler.WordCountMain /sogou.500w.utf8 /0717scheduler02
另外,修改队列属性、添加新队列是非常简单的。你需要编辑conf/capacity-scheduler.xml 并运行
[hadoop@node-01 Desktop]$ yarn rmadmin -refreshQueues
默认使用Capacity Scheduler
若要用Fair Scheduler的话,需要配置yarn-site.xml,将属性"yarn.resourcemanager.scheduler.class"的值修改成"org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler",如下
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
注意:同样,集群中所有yarn-site.xml文件要同步更新
在Fair调度器中,我们不需要预先占用一定的系统资源,Fair调度器会为所有运行的job动态的调整系统资源。如下图所示,当第一个大job提交时,只有这一个job在运行,此时它获得了所有集群资源;当第二个小任务提交后,Fair调度器会分配一半资源给这个小任务,让这两个任务公平的共享集群资源。
需要注意的是,在下图Fair调度器中,从第二个任务提交到获得资源会有一定的延迟,因为它需要等待第一个任务释放占用的Container。小任务执行完成之后也会释放自己占用的资源,大任务又获得了全部的系统资源。最终的效果就是Fair调度器即得到了高的资源利用率又能保证小任务及时完成.
在yarn-site.xml中设置yarn.scheduler.fair.preemption为true
cs