(七)Spark源码理解之TaskScheduler----part6

来源:互联网 发布:达内大数据课程怎么样 编辑:程序博客网 时间:2024/05/22 11:39

恩。。。。由于最近这段时间都在实习以及找工作,因此就将博客给落下了,现在继续将spark的部分"搬上"。。PS:虽然我自己也忘得差不多了。。

4.Executor

Executor类完成任务的装载,任务的运行等功能,它有个变量为ExecutorSource对象,这个对象主要实现注册executor的各项资源,在此省略不讲,此外Executor类有个核心方法launchTask(),该方法在之前的过程也稍微提到了,在此贴出其代码做详细的介绍

4.1 TaskRunner

TaskRunner(execBackend: ExecutorBackend, taskId: Long,serializedTask: ByteBuffer)是Executor中比较重要的一个类,它主要完成执行任务的功能,实现这一功能主要是依靠它的run()方法,因此关于TaskRunner我主要讲述下run方法,因run方法的代码略长,就不贴出来了,讲下它的基本过程:

获得当前时间作为startTime---->设置spark环境,获得序列器ser---->调用ExecBackend对象的statusUpdate方法更新任务的状态为运行--->设置taskStart为0,其作用在后述步骤中会提到--->清空累加器----->获得该任务的反序列化对象(该对象包含任务的文件,JAR包,以及任务本身),之后利用获得信息更新任务的文件,JAR包内容---->将进行上述操作之后的当前时间赋值给taskStart(我觉得这里有点不好,其实可以直接在这里声明taskStart,前面就可以不用声明了),作为在做好各项准备之后任务真正运行的开始时间----->调用Task类的run方法运行任务(实际上run()方法中调用了runTask()方法),获得value值,计算当前时间赋值给taskFinish---->将value值序列化为ByteBuffer---->更新该任务的各项指标(task.metrics),如主机名,任务运行时间等等--->处理该任务的结果(首先将该任务的value值加入到累加器中,与其他任务的value值进行merge--->生成一个DirectTaskResult对象,该对象包含了任务的value值和累加器的值--->序列化DirectTaskResult对象,若其大小超过了一定的限制,则将task转换为相应的TaskResultBlockId对象,之后调用BlockManager的putBytes将其存储在block中(之后会生成对应block的IndirectTaskResult对象,接着序列化该对象,这个对象就作为最终的任务结果),否则任务结果就为这个DirectTaskResult对象,不用存储在block中了,直接传送给应用程序)----->更新任务状态为完成Finished---->若前面的步骤出现异常,则处理各项异常错误,将任务从executor类中的runningTasks容器中移除(其添加过程在executor的launchTask方法中出现)

PS:Task有两种类型:ResultTask和ShuffleMapTask,run()方法最终调用的还是Task的runTask()方法,Task的两种类型分别有具体的runTask()实现方法

任务运行后会得到相应的任务运行的状态,如完成,失败等等,这个时候就又会调用DAGScheduler来处理各种相应事件,因此可以简要地说调度顺序为DAGScheduler----->TaskScheduler----->DAGScheduler

4.2 ExecutorBackend

ExecutorBackend即为executor的后台支撑服务,它有许多的实现方式(子类),即CoarseGrainedExecutorBackend,LocalBackend等

至此关于TaskScheduler的部分已经完成,下面总结下TaskScheduler是如何实现任务调度的,其中各个方法在上述已经详细介绍,可以参考上述介绍进行理解


未完待续。。。



0 0
原创粉丝点击