4

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

 3 years ago
source link: https://my.oschina.net/hncscwc/blog/5084319
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

YARN——正确理解容量调度的capacity参数 - hncscwc的个人空间 - OSCHINA - 中文开源技术交流社区

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

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

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

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

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

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

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

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

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

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

0b5289e7-70d5-431b-8a5f-5410b360ca77.jpg

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

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

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

12 * 1024 * 0.1 = 1228.8MB

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

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

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

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

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

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

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

a7ce46d7-82e9-4e24-a7d8-7e27894068ce.jpg

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

f8960fa8-dcf9-4c98-8f58-65791b8cd4b5.jpg

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

ff4eb35d-7ce2-454c-a488-fe42e6dfbae7.jpg

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

51f9ccfd-af42-4674-b053-d798acdfd18b.jpg

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

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

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

12 * 1024 * 0.05 = 614.4MB

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

b98ffaf8-c481-4a03-8d16-90c4a51c22cf.jpg

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

714f6923-675f-4ff1-8234-474fbb715710.png

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

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

【总结】


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

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

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

好了,本文就讲到这里,原创不易,点赞,在看,分享是最好的支持, 谢谢~

e6313787-4dfb-4385-8d0a-c0b0755af297.jpg

本文分享自微信公众号 - hncscwc(gh_383bc7486c1a)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK