SPARK3 基于YARN的EXECUTOR的动态申请详解

本文详细探讨了Spark3.1.1在YARN上动态申请Executor的流程,涉及ExecutorAllocationManager如何根据任务状态调整Executor数量,以及YarnAllocator如何与ResourceManager交互申请和释放Executor。内容包括Executor的超时逻辑、ExecutorMonitor与ExecutorAllocationListener的角色,以及AMRMClient的资源管理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近工作中遇到RM(ResourceManager)性能慢的问题,研究了一下RM的资源分配流程,因为内部流程还是比较复杂的,为了以后方便查阅,记录一下。在研究YARN容器的生命周期的过程中,从Applicaiton的提交,到最后的完成,整个流程中容器的分配和删除主要是ApplicaitonMaster发起的,由RM内部的Scheduler来管理分配。本篇文章还是聚焦在spark的executor的分配逻辑上, 关于YARN内部container的分配流程计划单独写一篇文章记录,这里就不过多介绍,简要的说明下YARN的RM内部的一些组件,对于后面executor的分配流程的理解会有帮助。

在RM内部主要是三个对外协议,

1. ApplicationClientProtocal 是负责跟client交互,client提交application, getApplicationReport/killApplication等. 对应RM中的组件是ClientRMService, 对应默认端口是 8032

2. ResourceTracker, nodeManager用来注册,和heatBeat的协议,在RM中的组件是ResourceTrackerService, 对应默认端口是 8031

3. ApplicationMasterProtocal, applicationMaster交互的协议,分有三个方法 registerApplicationMaster/finishApplicaitonMaster/allocate, 在RM中的组件是ApplicationMasterService, 对应的默认端口是 8030

我研究版本是基于spark3.1.1 以及hadoop cdh 2.6.0。

在spark3.1.1中,executor的申请我们生产上配置的是动态申请,管理executor申请的类是ExecutorAllocationManager,在SparkContext初始化的时候,就初始化好了,这个组件是在Spark的Driver端初始化的。

ExecutorAllocationManager里面包含了两个SparkListener,  ExecutorAllocationListener 和ExecutorMonitor, 这两个listener监听spark RDD执行过程中的stage和task事件,汇总task和executor的信息。

ExecutorAllocationManager 在初始好之后,启动一个内部线程,定期的执行schedule方法,

在schedule方法内部会根据ExecutorMonitor计算executor是否timeout, 如果有timeout , 就会调用killExectors释放executor.

 

executor的timeout的计算逻辑是根据executor是否有task在运行,是否有cache rdd block或者cache shuffle data来判定的。 如果有task运行,不计算该executor的timeout, 否则计算cache shuffle data 和 cache rdd block的timeout时间,取两者最小的。

在shecule方法内部还有另外一个逻辑是处理updateAndSyncNumExecutorsTarget. 这个方法里会计算targetNum of executor,这个是spark程序运行当前需要的executor的总量。计算的依据就是当前pendingTask的数量,这里主要就是依赖ExecutorAllocationListener 了,ExecutorAllocationListener 会监听Spark作业运行过程中的事件,统计pendingTask的数量,相关事件处理逻辑如下:

  1. 当stageSubmitted的时候,会把stage的task数量存放到stageAttemptToNumTasks中
  2. 当stageCompleted的时候,会从stageAttemptToNumTasks中删除该stage
  3. 当taskStart的时候,会把stageAttemptToNumRunningTask +1, 并根据task是否是speculative,把taskIndex加入到stageAttemptToSpeculativeTaskIndices中 或 stageAttemptToTaskIndices中。
  4. 当taskEnd的时候,如果task是失败的,并且不是specilative的,会把taskindex从stageAttempttoTaskIndices中删除。
  5. 还有其他监听speculative task的事件,就不一一列举了。。。

当ExecutorAllocationManager计算maxNumExecutorsNeededPerResourceProfile的时候,maxNeeded = (pending + running) * executorAllocationRatio / taskPerExecutor, 其中

pending 是所有stageAttempt的 pendingTask + pendingSpeculativeTasks.
pendingTask = totalNumTask - numRunning(保存在stageAttempToTaskIndices中的taskindex的数量)
pendingSpeculativeTasks 是 numTotalTaskOfSpeculative – numRunningOfSpeculative.
这些数值都是在监听staage/task事件过程中更新的。
 

maxNeeded的第二种算法是 unschedulableTaskSets * executorAllocationRatio / tasksPerExecutor + executorMonitor.exe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值