Flink源码解析(十四)——Flink On Yarn ExecutionGraph调度及TaskManager启动过程解析

一、ExecutionGraph调度解析

上一篇随笔最后一部分介绍JobMaster启动过程由两大步骤组成,一是创建2个心跳服务,JobMaster -> TaskManager的心跳服务、ResourceManager -> JobMaster。二是执行ExecutionGraph调度。本节详细解析ExecutionGraph的调度过程。

1、由上篇随笔可知,在JobMaster启动时会触发ExecutionGraph的调度过程,调度入口即JobMaster.startScheduling()方法。

获取流式Region,即上下游需要同时调度的Region,常规的Flink流式应用上下游基本上都需要同时调度。开始调度。

对每一个符合条件的SchedulingPipelinedRegion开始分配slot并部署,在Flink刚启动阶段还没有可用的slot,需要向资源管理框架Yarn:ResourceManager申请container来分配可用的slot资源。上述即为ExecutionGraph的调度过程,下面继续分析调度过程中slot的分配过程。

下图中allocateSlotsFor(...)方法负责向Yarn:ResourceManager申请新的container获取slot资源。waitForAllSlotsAndDeploy(...)负责在获取slot资源后部署Task的过程,Task部署过程在下一篇随笔中解析。下面着重分析allocateSlotsFor(...)方法。

下面是方法的调用链路:

DeclarativeSlotPoolBridge.requestNewAllocatedSlot(...)
DeclarativeSlotPoolBridge.internalRequestNewSlot(...)
DeclarativeSlotPoolBridge.internalRequestNewAllocatedSlot(...)

Consumer<? super Collection<ResourceRequirement>> notifyNewResourceRequirements;成员指得是DeclarativeSlotPoolService.declareResourceRequirements(...)方法

此处resourceTracker.notifyResourceRequirements(...);只是记录下slot的分配行为,真正的分配动作在checkResourceRequirementsWithDelay();实现

DeclarativeSlotManager.checkResourceRequirementsWithDelay()
DeclarativeSlotManager.checkResourceRequirements()
DeclarativeSlotManager.tryFulfillRequirementsWithPendingSlots(...)
DeclarativeSlotManager.tryAllocateWorkerAndReserveSlot(...)

经过一系列方法的调用到tryAllocateWorkerAndReserveSlot()方法,进入TaskExecutorManager.allocateWorker(...)的方法中。

TaskExecutorManager.allocateWorker(...)
TaskExecutorManager.declareNeededResourcesWithDelay()
TaskExecutorManager.declareNeededResources()

进到ActiveResourceManager类中。

ActiveResourceManager.declareResourceNeeded(...)
ActiveResourceManager.checkResourceDeclarations()
ActiveResourceManager.requestNewWorker(...)

跳转到YarnResourceManagerDriver.requestResource(...)方法,在该方法里,会调用方法addContainerRequest(...),最后生成一个ContainerRequest参数,借用resourceManagerClient成员变量来请求Yarn:ResourceManager资源框架管理的container资源。

在resourceManagerClient初始化时会传入一个YarnContainerEventHandler实例,作用是事件发生时回调对应的事件处理动作。当Yarn:ResourceManager资源框架分配好container资源时,会回调该实例的onContainersAllocated(...)方法。

方法调用链路如下:

YarnResourceManagerDriver.onContainersOfPriorityAllocated(...)
YarnResourceManagerDriver.startTaskExecutorInContainerAsync(...)
YarnResourceManagerDriver.createTaskExecutorLaunchContext(...)

到调用Utils.createTaskExecutorContext(...)方法时,传入TaskManager的实现类信息作为TaskManager的启动入口。即yarn container容器启动时会执行YarnTaskExecutorRunner类的main(...)方法。

在创建完ContainerLaunchContext实例后,随即调用nodeManagerClient.startContainerAsync(container, context);方法,开始TaskManager的启动工作。

以上即为ExecutionGraph的调度过程及初次请求slot资源时,TaskManager的配置启动信息,下面继续分析TaskManager的启动过程。

二、TaskManager启动过程解析

上节最后分析到ContainerLaunchContext实例生成过程,同时也看到配置好了YarnTaskExecutorRunner启动过程,它就是一个普通的java类,包含main(...)方法,通过java命令启动。本节分析下YarnTaskExecutorRunner的启动过程。

1、通过java命令触发main(...)方法执行,进入runTaskManagerSecurely(...)方法中,加载配置文件生成配置项,执行后续启动操作。

生成TaskManagerRunner实例并启动。

在生成TaskManagerRunner实例时,构造函数第三个参数是一个TaskExecutorService类型的实例,具体生成过程如下:

生成TaskExecutor实例,解析taskmanager运行时需要的资源参数,然后从Configuration中解析出TaskManagerServices所需要的配置。

根据上面生成的TaskManagerServicesConfiguration配置项,生成TaskManagerServices实例。在生成过程中Flink会创建TaskManager的关键组件,IOManager、ShuffleEnvironment、BroadcastVariableManager等。

最后解析TaskManager的配置项并利用上面生成的信息构造出TaskExecutor实例。

TaskManagerRunner实例生成后紧接着调动其start()方法,其中startTaskManagerRunnerServices()方法主要负责构建TaskExecutorService实例,构造完成后调用其start()方法。

在构建TaskExecutorService实例之前,会先生成rpc服务、高可用服务、线程池等,最后利用这些信息构建TaskExecutorService实例。

taskExecutorService.start()方法最后执行的是TaskExecutor.start()方法。TaskExecutor继承于RpcEndpoint,所以当调用RpcEndpoint的start()方法时,会回调TaskExecutor的onStart()方法。如下:

首先会创建该TaskExecutor到ResourceManager的链接,其次赋予TaskSlotTable释放slot和slot超时的具体操作,启动Job Leader服务,从本地文件系统恢复JobTable、TaskSlotTable等。

以上即为TaskManager启动过程解析。

posted @ 2024-02-03 20:14  有一个娃  阅读(284)  评论(0编辑  收藏  举报