目录
Worker接受执行
如红箭头所示,worker大致从接受到task,提交线程执行,最后响应结果结束。
TaskExecuteProcessor:
worker入口,接受master提交的TaskExecutionContext。
1. 缓存TaskExecutionContext。特别注意,这里TaskExecutionContext第一次复制为TaskRequest对象(简称TR1),缓存到TaskExecutionContextCacheManager
2. 缓存NettyRemoteChannel到TaskCallbackService中,后面于master通信都要用到
3. 响应ACK command,command里记录了task得worker host,state,log path,start time。并且worker服务会缓存ack command到RetryReportTaskStatusThread。RetryReportTaskStatusThread是个轮询线程,不断的重新发送command
4. 创建TaskExecuteThread线程(传入TaskExecutionContext对象),并添加到WorkerManagerThread里的队列中,等待真正提交执行。
WorkerManagerThread:
主要有两个组成:
1. workerExecuteQueue队列,用于接受缓存TaskExecuteProcessor提交的线程
2. ExecutorService线程池,用于提交workerExecuteQueue队列里的线程,该线程池可执行线程数可配置,也是设置worker的并发度
工作原理:本质是个轮询线程,不断从workerExecuteQueue队列获取TaskExecuteThread线程, 利用ExecutorService进行提交执行。
TaskExecuteThread:
真正的执行线程。
1. 传入TaskExecutionContext对象第二次复制为TaskRequest对象(简称TR2)
2. 根据task类型,利用TaskChannel实例化一个真正的task(传入TR2对象),比如shell,java等(继承AbstractTask),方法有init(),handle(),cancelApplication()等
1) handle()是核心执行方法,执行中会生成processId(任务进程ID) ,yarn applicationId,执行状态结果等
3. 响应responseCommand(result command),并缓存result command到RetryReportTaskStatusThread
4. 释放task缓存
RetryReportTaskStatusThread:缓存ack result command,如果正常响应command失败,该轮询线程会持续发送,一直到收到master响应的DBcommand。
Worker注册的Processor
TaskExecuteProcessor: 不在赘述
DBTaskAckProcessor和DBTaskResponseProcessor:
1. 接受master发出的DBcommand。
2. 清除RetryReportTaskStatusThread里缓存的ack result command
思考1
TaskExecutionContext 和 TaskRequest?
以kill为例,目前海豚kill是从TaskExecutionContextCacheManager里获取TaskRequest(TR1),进而获取processId等信息进行kill操作。从上图看,task需要将这些重要信息同步到TR1,源码实现
taskRequest.setProcessId(processId);
boolean updateTaskExecutionContextStatus =
TaskExecutionContextCacheManager.updateTaskExecutionContext(taskRequest);
在task内,使用TR2设置processId,然后更新TaskExecutionContextCacheManager为TR2。