Spark源码解析:TaskSetManager 任务推断执行源码解析。

1、TaskSetManager的概述

TaskSetManager也实现了Schedulable特质,并参与到调度池的调度中,TaskSetManager对TaskSet进行管理,包括任务推断、Task本地性、并对Task进行资源分配。TaskSchedulerImpl依赖于TaskSetManager.

2、推断执行

在Hadoop2.x.x版本中,当一个应用向Yarn集群提交作业后,此作业的多个任务由于负载不均衡、资源分布不均等等原因都会导致各个任务运行完成时间不一致,甚至会出现一个Task尝试明显慢于同一作业的其他作业。好在Mr提供了任务推断执行机制,当有必要时就启动一个备份任务,最终会采用备份任何和源任务中率先执行完的结果作为最终结果。

与Hadoop类似,Spark中的Pool与TaskSetManager也提供了spark任务推断执行的机制,其可分为两类:1、可推断任务执行的检测与缓存(pool与TaskSetManager的checkSpeculatable)  2、从缓存中找到可推断任务进行推断执行(TaskSetManager的dequeueSpeculativeTask)

1)TaskSetManager的checkSpeculatableTasks(用于检查当前TaskSetManager中是否有需要推断的任务)

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第1张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第2张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第3张图片

该方法的主要执行步骤如下:

1、计算进行推断的最小完成任务数(开始推断的任务分数(默认为0.75)×numTasks的成绩向下取整)

2、计算出进行推断的最小已运行时间

3、遍历正在运行的Task的TaskId集合,取出其taskInfo和index,将符合推断条件的TaskSet中的task放入speculatableTasks中。推断条件包括还未执行成功、复制运行数为1、运行时间大于最小已运行时间,并且speculatable中没有当前task的index。那么返回true.

 2)dequeueSpeculativeTask(用于根据指定的host、Executor和本地性级别,从可推断的Task集合中找出可推断的Task在TaskSet中的索引和相应的本地性级别。

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第4张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第5张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第6张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第7张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第8张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第9张图片

该方法的主要执行步骤如下:

1、从speculatable中移除已经完成的task,保留还未完成的task

2、对于speculatableTasks中的所有未在指定的Host上尝试运行,且指定的Host和Executor不在黑名单的所有task,根据参数指定的host、Executor和允许的本地性级别,按照PROCESS_LOCOL(本地进程)、NODEL_LOCAL(本地节点)、NO_PREF(没有偏好)、RACK_LOCAL(本地机架)、ANY(任何)从高到底依次遍历,返回可推断的Task集合中的Task在TaskSet中的索引和相应的本地性级别。

3、Task本地性 

与Hadoop类似,Spark对任务的处理也要考虑数据的本地性,好的数据本地性能够大幅度减少节点间的数据传输,提升程序执行效率。Spark目前支持5种本地性级别,由高到底分别为:PROCESS_LOCOL(本地进程)、NODEL_LOCAL(本地节点)、NO_PREF(没有偏好)、RACK_LOCAL(本地机架)、ANY(任何)。

TaskSet中可以有一到多个本地性级别,但在给Task分配本地性时只能是其中的一个。TaskSet中所有Task都具有相同的允许使用的本地性级别,但在运行过程中可能因为资源不足,运行时间等因素,导致同一TaskSet中的各个Task的本地性级别可能不同。

1)computeValidLocalityLevels(用于计算有效的本地性级别,返回所有可用的本地性级别)

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第10张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第11张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第12张图片

举例:即pengdingTasksForExecutor中的ExecutorId有存在于TaskSchedulerImpl的executorIdToRunningTaskIds中,那么允许的本地性级别中包括PROCESS_LOCAL

2、getLocalityWait(根据参数 某个本地性级别,用于获取某个本地性级别的等待时间)

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第13张图片

3、getLocalityIndex(用于从myLocalityLevels中找出指定的本地性级别所对应的索引)

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第14张图片

4、getAllowedLocalityLevel(用于获取允许的本地性级别)

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第15张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第16张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第17张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第18张图片

Spark源码解析:TaskSetManager 任务推断执行源码解析。_第19张图片

1)按照索引从高到底从读取本地性级别,然后执行以下操作:

    调用moreTasksToRunIn方法判断本地性级别对应的待处理Task的缓存结构中是否有Task需要处理

    如果没有Task需要处理,则将最后的运行时间设置为curTime

    如果有Task需要处理且curTime与最后运行时间的差值大于当前本地性级别的等待时间,则将最后的运行时间增加当前本地性级别的等待时间(这样实际将跳入更低的本地性级别)

    如果有Task需要处理,且curTime与最后运行时间的差值小于当前本地性级别的等待时间,则返回当前本地性级别

 2) 如果上一步未能找到允许的本地性级别,则返回最低的本地性级别

你可能感兴趣的:(Spark源码解析:TaskSetManager 任务推断执行源码解析。)