前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >issue:yarn-11396

issue:yarn-11396

作者头像
陈猿解码
发布2023-02-28 15:13:27
2650
发布2023-02-28 15:13:27
举报
文章被收录于专栏:陈猿解码

在容量调度方式中,队列的capacity参数是作用于单个用户可以使用的资源上限,这个在文章《YARN——正确理解容量调度的capacity参数》一文中详细讲解过。

然而,最近一次发测自验过程中,发现单个用户提交的任务,其资源使用超过了队列的capacity配置参数,甚至是几乎用满了集群的全部资源。

本文就该问题进行分析总结。


前两天,在版本发测自验时,同事运行了一个flink任务,然后去吃饭了,回来正准备看运行结果时,任务还未结束,但发现该任务用光了集群的所有资源。

于是问了我一句,一个队列在capacity配置为30%,maximum-capacity配置为100%的时候,单个任务能用到多少资源?

我信心满满地告诉他:单个用户最多能用集群30%的资源,也就是capacity配置的值,多个用户累加在一起可以用满集群的全部资源。

同事:我这单个用户提交的单个任务,已经用完了集群的全部资源,你要不帮我看下?

我:额,有没有可能是最后一个container资源申请的时候,资源非常大导致出现了该问题呢。

同事:没有,总共申请了400多个container,每个container都是3核2G的资源。

我:哦,这样的话,应该是不可能申请到这么多资源的才对,顶多也就30%多一点,那有没有可能是先运行了任务,然后调整了队列的资源大小呢?

同事:我看过日志了,队列的资源大小一直没有调整过,就是这么多。

我:那你把环境发我,我看下吧。

登录到环境汇中,看了下RM的日志,发现队列里面只有一个任务(也就是有问题的这个flink任务),但是该flink任务重试了多次,也就是jobmanager退出后,yarn重新拉起了一个新的jobmanger,而jobmanager每次都申请100多个container(taskManager),累计400多个container,最终将资源全部用完。

看到这里,开始疑惑起来,jobmanager退出重试是符合逻辑的, 但是重试后为什么申请container还能分配到资源呢,不应该是达到用户资源使用上限,不会调度分配资源才对啊。

日志无法分析出结果,那就还得源码来说话!

经过一番分析后,还是从源码中找到了问题,关键步骤及代码如下所示:

  • AM(异常)结束后,最终会触发RM内部产生移除attempt事件,调度器在处理移除该事件时,根据任务的配置决定是否将该attempt申请的container全部kill,然后由任务所属的队列进行处理。

在队列的处理中,主要是重新计算已使用的资源,包括队列中该用户已使用的资源。

上面这两段代码中,有两个关键信息:

1、第一步中,根据任务的配置决定是否将该attempt申请的container全部kill,具体来说,这个配置项为:"keepContainersAcrossApplicationAttempts"。其作用也就是当AM异常时,不主动杀掉AM所申请出来的正在运行的container,当创建新的AM时,主动告知之前已运行的container信息。避免误杀从而提高任务的处理速度。

但是,在MR/Spark/Flink三种主流任务类型中,只有flink对该配置项的值设置为true,即仅有flink支持该配置项。

2、在第二步中,在用户管理里删除用户的条件是:该用户当前没有活跃的attempt(包括正在运行的和等待运行的attempt)。

注:在每个队列中都维护了一个用户管理信息,里面记录了当前队列中所有用户提交的任务数、以及累计使用的资源,方便进行调度时进行判断,是否还可以继续分配资源。

对应的结构体如下所示:

再接着来看任务重试,即重新创建新的attempt时的逻辑:调度器在处理添加attemtp事件时,先在内存记录相关信息后,然后交由任务提交的队列处理,而在队列的处理逻辑中,主要就是在用户管理中,查找对应的用户信息,如果没有该用户,则创建一个新的用户信息,然后记录用户的相关信息。

此后进行调度时,判断该用户的资源是否超过使用上限,如果没有则可以分配资源,否则会提示该用户在当前队列中已经超过限制,无法继续分配资源。

如此一来,整个问题可以全部得到解释:

即队列中的首个flink任务,正常运行一段时间后,AM(jobmanager)异常退出;

接着,在rm调度器内部清除attempt后,发现该用户没有活跃的attempt,因此在队列中连同用户信息一并删除(但此时已经分配调度的container,也就是taskmanager仍旧在运行);

此后,任务进入重试逻辑,重新添加一个新的attempt,在队列中找不到该用户信息,因此重新初始化并添加该用户信息,但此时新添加用户时并没有将之前未删除的container的资源计算在内,而是简单的将已使用的资源初始化为0;

再然后,随着NM的心跳上报,开始分配资源进行调度,由于内存中记录的该用户当前已使用资源未达到限制,因此允许资源分配。

这样,当AM多次退出重试后,每次都能分配到资源,也就将集群的资源全部用完。

知晓完整流程后,自然也就能轻松地复现问题。

注:这是在AM进行一次重试后的截图:上面是队列中的用户统计信息,AM每次申请5个container,一个是任务的统计信息,两者明显是不一致的。

对于该问题,其实比较好解决,我们当前也已经向社区提单,并准备了patch(还未推送),有兴趣的朋友,可以去查看issue并关注下后面的patch(https://issues.apache.org/jira/browse/YARN-11396)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈猿解码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档