TaskManager执行任务
当一个任务被JobManager部署到TaskManager之后,它将会被执行。本篇我们将分析任务的执行细节。
submitTask方法分析
一个任务实例被部署所产生的实际影响就是JobManager会将一个TaskDeploymentDescriptor对象封装在SubmitTask消息中发送给TaskManager。而处理该消息的入口方法是submitTask方法,它是TaskManager接收任务部署并启动任务执行的入口方法,值得我们关注一下它的实现细节。
submitTask方法中的第一个关键点是它先构建一个Task对象:
val task = new Task(
tdd,
memoryManager,
ioManager,
network,
bcVarManager,
selfGateway,
jobManagerGateway,
config.timeout,
libCache,
fileCache,
runtimeInfo,
taskMetricGroup)
该Task封装了其在TaskManager中执行时需要的一些关键对象。task对象将会被加入TaskManager中的一个ExecutionAttemptID与Task的Map中,如果发现该ExecutionAttemptID所对应的Task对象已存在于Map中,则将原先的Task实例重新放回到Map中,同时抛出异常:
val execId = tdd.getExecutionId
val prevTask = runningTasks.put(execId, task)
if (prevTask != null) {
runningTasks.put(execId, prevTask)
throw new IllegalStateException("TaskManager already contains a task for id " + execId)
}
如果一切正常,接下来就启动线程并执行任务,接着发送应答消息进行回复:
task.startTaskThread()
sender ! decorateMessage(Acknowledge)
submitTask方法比起JobManager的submitJob方法,逻辑和代码量都相对简单。我们会进一步分析两个过程:
Task对象的构造方法
Task作为一个线程,其run方法的实现
首先关注的是Task的构造方法,Task作为TaskManager的启动对象,其需要的参数基本都跟其执行有关,参数如下:
public Task(TaskDeploymentDescriptor tdd, //任务描述符
MemoryManager memManager, //内存管理器
IOManager ioManager, //IO管理器
NetworkEnvironment networkEnvironment, //网络环境对象,处理网络请求
BroadcastVariableManager bcVarManager, //广播变量管理器
ActorGateway taskManagerActor, //TaskManager对应的actor通信网关
ActorGateway jobManagerActor, //JobManager对应的actor通信网关
FiniteDuration actorAskTimeout, //actor响应超时时间
LibraryCacheManager libraryCache, //用户程序的Jar、类库缓存
FileCache fileCache,