YARN——正确理解容量调度的capacity参数

容量调度器中,配得最多的应该就是capacity和maximum-capacity了,一个是当前队列的资源容量,一个是队列可使用的最大容量。多个队列的容量之和为100。

 

maximum-capacity这个参数还好理解,即队列可使用资源的上限。

假如有多个队列,每个队列都将maximum-capacity的值设置成与capacity一样,意味着每个队列只能使用固定大小的资源,不能超额使用其他队列空闲资源,这样,也就可能出现资源浪费或利用率低的情况。

 

因此,通常该值会设置成比capacity大。例如都设置为100,也就是每个队列最大都可以使用集群的全部资源。

但既然最大都可以使用集群的全部资源,那么capacity参数的作用和意义到底是什么,该参数又是如何限制用户资源使用的。

 

查看了官方文档,网上也看了不少文章,始终觉得没有讲透capacity这个参数的意义,索性直接撸源码。

 

结合源码,并对照日志,确认了几个关键点后,对自己的结论很是自信,立马邮件同步给组内的小伙伴。

 

队列的capacity参数是单个用户在该队列中所能使用资源的上限。

 

由于允许多个不同的用户向同一个队列提交任务,因此多个用户的不同任务的资源叠加起来可以超过capacity,但是不能超过maximum-capacity。

 

然而,没过多久,就收到了同事的答复邮件,并附带如下图示:队列配置10%的资源,用户提交了一个任务,使用的资源远超10%!

 

 

收到邮件,瞬间觉得脸已被打肿,但是之前研究相关源码,确定应该是会限制的啊,难道是哪个细节没注意到,代码走了其他分支?

 

带着疑问再次走读相关代码,并进行一系列测试,发现该现象是可以解释的,之前给出的结论也仍旧还是成立的。

 

当前集群的总资源为12GB,队列容量设置为10%,因此该队列上,单个用户理论上资源使用的上限为:

12 * 1024 * 0.1 = 1228.8MB

注:该队列的父队列为root,如果父队列不是root,则需要继续乘父队列的容量百分比。

 

由于配置的集群资源分配最小单位为1024MB,因此需要向上取整,即2048MB。也就是单个用户使用的资源上限为2048MB。

 

当spark任务的driver启动时(申请的资源为2048MB),当前队列中,该用户已使用的资源为0,未超过上限,因此可以为其分配资源,即driver可以成功启动。

 

driver启动后继续申请启动两个executor,每个executor申请www.rsxedu.com分配2048MB。yarn调度时,发现该用户当前已使用资源为2048MB(为driver分配的资源),仍旧未超过上限,因此继续为一个executor分配了资源。但轮到第二个executor时,该用户当前已使用的资源变为了4096MB,超过了上限,因此没有为该executor分配资源。

 

也就是说:虽然队列容量配置的是10%,但并不是严格按照10%来限制,即允许超额使用。只要用户当前已使用资源没有超过上限,就可以继续分配(即便分配后会超过上限);但一旦当前已使用的资源超过了上限时,则不能再继续分配资源。

 

为了验证上面的结论,再进行如下测试:队列的容量仍旧配置为10%,同时将AM资源使用限制调高(maximum-am-resource-percent),防止因AM资源受限出现干扰。

 

先提交一个spark任务,情况和上面的情况一样,再次提交一个任务时,第二个任务始终处于ACCEPT状态,spark任务的driver都没有进行资源分配。

 

 

同时,从界面上可以看到任务的诊断信息为:超过用户资源使用上限。

 

 

在这个基础之上,切换用户,再提交一个spark任务,发现任务可以正常运行,如下图所示:

 

 

将该队列的AM资源使用限制调回到原来的值,再来进行www.meimeitu8.com测试,第二个任务同样处于ACCEPT状态,但界面上看到的信息则不同,提示为:超过用户AM最大使用资源。

 

 

到这里,也就验证了之前的结论是正确的了。

 

将上面的测试过程,相关截图,以及结论总结进行了汇总,然后邮件进行了回复,以为可以告一段落了。但是,过了一会,再次收到了邮件,回复如下:

 

将队列的容量设置为5%,那么理论上该队列单个用户的最大使用资源为:

12 * 1024 * 0.05 = 614.4MB

向上取整为1024MB,按你的结论,提交的任务应该都无法分配资源,处于ACCEPT状态才对,然而还是进行了资源的分配,如下图所示:

 

 

看到邮件后,心情很平淡,因为之前的研究过程中,已经发现了这个问题,直接贴一段代码说明:

 

 

也就是说,只要当前队列中没有任务在运行,提交任务时,即便是超过了用户可使用资源的上限,仍旧会进行资源的分配,保证有一个任务可以运行

 

另外,从上面的图中,还可以看出一点,该任务只分配了2048MB,也就是driver的资源,而driver申请启动的executor均未分配到任何资源,因为当前已使用资源已经超过了上限。

 

【总结】


队列的capacity参数是作用于单个用户的资源使用上限,真正调度分配时只要用户已使用资源未超过上限,就可以继续分配(分配后可以超过上限)。

 

当然决定用户资源使用上限的还有其他参数,例如user-limit-factor,minimum-user-limit-percent等,后续文章再单独说明。

 

另外,整个讨论过程下来,体会到源码是不会说谎的,看源码的同时还是要多动手测试验证,才能真正做到正确理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值