ITPub博客

首页 > 数据库 > 数据库开发技术 > 记一次YARN队列资源不足导致的任务失败

记一次YARN队列资源不足导致的任务失败

原创 数据库开发技术 作者:安瑞哥是码农 时间:2022-03-09 18:59:59 0 删除 编辑


前言

今天团队一小伙伴火急火燎告诉我,他提交的一个spark任务怎么着都跑不起来,一启动就报错,明明同样的代码几天前还运行好好的,怎么今天就【失灵】了呢?因为我当时在忙其他事情,所以让他先找找原因,他检查了半天,没有找到,只把代码逻辑前后检查了一遍又一遍后确认他代码没有问题,再次找到我,把【锅】成功甩给了我。

那我哪能忍,于是吭哧吭哧把原因找到后,然后又一顿噼里啪啦操作,把问题给解决了,成功获得了他的【大拇指】。




01

—

问题表现


用spark-submit在spark客户端机器通过命令行端提交job之后,任务一直处于ACCEPT的状态,然后一会就直接退出了。

从客户端提交的console端日志反映的直观信息来看,就是跟集群中的某个机器进行通信时超时,然后就退出了,其实并没有什么有效信息。

然后再看YARN记录的日志信息,看有没有什么新的发现:

依然没有获得有效日志信息,光一个socket连接超时,很难知道根本原因在哪(当然,先确认任务提交的客户端跟要通信的服务器间的网络是正常的)。
而且类似这样socket timeout的问题,甚至很多时候它都不是问题的原因,而是问题导致的一个结果。




02

—

问题定位


在解决这种一眼找不到原因的问题时,首先不要着急,根据一定的方法论进行逻辑推理,是一定可以把问题原因给揪出来的,你得先有这样的自信。
第一步,虽然日志没有明确告诉原因,但是却也提供了一个隐藏的信息,那就是:任务压根就没有提交到YARN上面去。因为运行日志为空,只有job提交过程的日志,先排除代码本身的逻辑错误可能,于是这个【锅】就直接扣到了YARN头上;
第二步,既然定位是YARN的问题,那就首先来看YARN的服务正不正常,一看服务也正常,而且上面还跑了很多正在执行的任务,于是排除YARN服务本身问题;
第三步,既然确定是YARN的【锅】,而且它的服务又正常,那问题出在哪呢?于是我们就要想想,一个任务提交的过程是什么样的:    
1,客户端找到ResourceManager(简称RM),告诉它你要运行job;
2,RM收到请求后,会根据你的要求开始向集群申请硬件资源;
3,申请到资源后,你的job就被【分治】成多个task,分配到多台机器上,提交成功(也就是从ACCEPTED状态变为Running状态);
4,job开始执行业务逻辑运算,直到停止。
搞清楚这个过程后,思路开始清晰起来,很明显,问题出现在过程3上。
第四步,定位到是申请资源失败而导致的ACCEPTED无法变成RUNNING,于是我们再去 看YARN的资源问题,

如图发现这几个选项的结果都为0,意味着YARN中并没有因为资源不足而积压的任务,而且从YARN的资源使用情况来看,也验证了这一点。

发现无论是内存资源还是CPU资源都是足够的。那就奇怪了,资源够,网络正常,但是却提交不成功(莫非灵异事件出现了吗)?那就只有一个可能:YARN对资源做了限制。
第五步,定位到资源限制后,就来分析下YARN是如何限制资源的,一般来说有2种限制策略:
1,对队列资源进行限制;
2,对个人用户进行资源限制。
而我知道这个集群暂时并没有对个人用户在使用资源时做出限制,因此问题就一定出在【队列资源】上。
第六步,找到队列资源,查看队列资源的分配情况:

可以看到当前YARN配置了2个队列,其中default队列资源占比为60%,而另一个llap队列资源占比为40%,当前提交的队列因为没有指定具体用哪个队列,因此默认使用的是default队列。而通过检查发现,该队列在这个任务提交前期资源就已经占用了58%,剩下2%的资源已经不够这个任务运行的需要,才导致了这个小伙伴的任务提交一直失败。

到这里,问题定位成功。



03

—

问题解决


    既然定位到问题了,那解决起来就简单多了,要么扩大这个队列的资源,要么等待其他任务运行完,等资源释放再提交。

    因为考虑到这个任务的紧急性,以及另一个队列llap的资源确实分配的有点多了,于是决定调整这两个队列的资源配额比例,将原本default的60%改为80%,而原本的llap从40%改为20%(注意所有队列的资源总和加起来必须小于等于100%)。

    具体改法如下,找到YARN的配置文件的scheduler选项(我这里因为是用Ambari来管理,因此可以直接通过页面来修改,如果是其他方式管理配置文件,改法类似),

    另外,我这个YARN用的是capacity scheduler,如果你的集群用的其他scheduler,配置也是类似的。

    最后refresh一下你的scheduler就可以了,注意只用refresh,不需要重启你的YARN服务。

再次提交任务,发现可以正常运行了。


问题解决...


04

—

想起前段时间的一个坑


在解决完这个问题后,突然想起前段时间到的类似一个问题,问题的表现一模一样,只不过上次不是因为队列资源不够,而是因为这个参数
yarn.scheduler.capacity.maximum-am-resource-percent
 默认的数值太低(只有0.1)。
这个参数是用于设置所有提交的job中ApplicationMaster的资源比例上限,该参数通常用于限制处于活动状态的job数量。这个参数对于那些运行【大任务】的集群来说还好,因为每个job占用的资源够多,因此集群job数量反而不大。
    但是对于运行很多【小任务】的集群来说,因为每个job虽然占用的资源比较少,会导致集群的job数量很多,而这个时候这个参数的限制就比较明显。
这个参数的默认值只有0.1,也就是说,你提交的所有job中,所有的ApplicationMaster进程(一个job对应一个该进程)所占用的资源最多只能占YARN资源的10%,一旦超过,job将无法提交,也就会出现文章开始的那种情况。
解决办法:可以根据实际情况,将该值调大一些。




结语

——

实际工作中我们会遇到非常多这样的问题,在遇到类似表面没有头绪的问题时,一定不要慌张,自乱阵脚,或者干脆甩锅,撇清责任,解决问题才是根本。

用你的强逻辑能力去分析,从【道】的高度来对问题进行拆解,然后从【术】的层面对其进行解决。其实今天这个问题一点都不难,你只需要稍微沉下心来分析一下,就很容易找到问题。

共勉...







如果你觉得我进的还凑合,欢迎找我交流探讨...



原文作者:安瑞哥是码农;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-02-16

  • 博文量
    228
  • 访问量
    115431