Spark通过Livy创建会话报用户容量达上限如何排查解决
问题背景
通过Livy REST API在Apache Spark中创建会话时任务失败,返回错误:User capacity has reached its maximum limit.。
当前操作用户账号下已有1个正在运行的Spark作业,无法确定具体是哪项容量指标达到上限,也不清楚如何通过调整Spark配置参数解决问题。
故障相关日志
22/05/30 19:18:51 INFO Client: Submitting application application_1653913029140_0247 to ResourceManager 22/05/30 19:18:51 INFO YarnClientImpl: Submitted application application_1653913029140_0247 22/05/30 19:18:51 INFO Client: Application report for application_1653913029140_0247 (state: ACCEPTED) 22/05/30 19:18:51 INFO Client: client token: N/A diagnostics: [Mon May 30 19:18:51 -0300 2022] Application is Activated, waiting for resources to be assigned for AM. User capacity has reached its maximum limit. Details : AM Partition = <DEFAULT_PARTITION> ; Partition Resource = <memory:2662400, vCores:234> ; Queue's Absolute capacity = 32.0 % ; Queue's Absolute used capacity = 40.76923 % ; Queue's Absolute max capacity = 100.0 % ; Queue's capacity (absolute resource) = <memory:851967, vCores:74> ; Queue's used capacity (absolute resource) = <memory:1085440, vCores:106> ; Queue's max capacity (absolute resource) = <memory:2662400, vCores:234> ; " ApplicationMaster host: N/A ApplicationMaster RPC port: -1 queue: default start time: 1653949131433 final status: UNDEFINED tracking URL: http://vrt1557.bndes.net:8088/proxy/application_1653913029140_0247/ user: s-dtl-p01 22/05/30 19:18:51 INFO ShutdownHookManager: Shutdown hook called
现有运行作业Spark配置
conf = {'spark.yarn.appMasterEnv.PYSPARK_PYTHON': 'python3', 'spark.cores.max': 50, 'spark.executor.memory': '10g', 'spark.executor.instances': 100, 'spark.driver.memory' : '10g' }
本次启动失败的作业未配置任何自定义Spark参数,完全使用集群默认配置值。
核心疑问
YARN队列存在多项与应用资源申请交互的配置参数:
- 本次故障中到底是哪项资源被耗尽?
- 如何基于上述日志定位具体的耗尽资源?
问题解答
耗尽的资源维度
本次故障触发的是YARN容量调度器的单用户资源配额限制,并非YARN队列整体资源、集群节点资源被耗尽。
定位逻辑
- 先通过报错关键词锁定排查范围:报错明确提示
User capacity has reached its maximum limit,可以直接排除队列整体容量不足、节点空闲资源不足这类问题,问题边界缩小到「提交任务的用户在对应队列的资源配额被打满」。 - 提取日志中的队列资源核心数值做换算:
- default队列配置的保底容量占集群总资源的32%,折算为绝对资源是
内存851967MB(约832G)、vCore74个 - 容量调度器默认配置
user-limit-factor=1,即单个用户最多可申请的资源上限等于所在队列的保底容量,也就是上述的832G内存、74个vCore - 当前该队列已用资源为
内存1085440MB(约1060G)、vCore106个,全部来自当前账号下正在运行的Spark作业,已经远超单用户配额
- default队列配置的保底容量占集群总资源的32%,折算为绝对资源是
- 结合运行作业配置做交叉验证:运行中作业配置了100个10G内存的executor,加10G内存的driver,仅配置项声明的内存就达到1010G,算上AM占用、executor/driver的内存开销(默认是内存配置的10%左右),总内存占用刚好和日志中1060G的已用值吻合。
- 容易混淆的调度逻辑说明:YARN容量调度器的单用户配额校验只在新提交应用申请资源时触发,如果提交作业时队列有空闲资源,已经运行的作业可以弹性使用超出单用户配额的资源,调度器不会强制回收已经分配出去的资源;但只要同用户提交新作业时,用户已占用资源超过配额,新作业哪怕只申请AM所需的少量资源,也会被直接拦截,卡在ACCEPTED状态报本次的错误。
当前运行的作业存在明显的配置超配问题:同时配置spark.executor.instances=100和spark.cores.max=50本身存在冲突,100个10G的executor总内存申请已经远超单用户配额,直接堵死了同账号下新作业的提交通道。
内容的提问来源于stack exchange,提问作者neves
相关产品推荐
相关产品推荐

