4.3.2 本地化调度
DAGScheduler
切割Job
,划分Stage
, 通过调用submitStage
来提交一个Stage
对应的tasks
,submitStage
会调用submitMissingTasks
,submitMissingTasks
确定每个需要计算的 task
的preferredLocations
,通过调用getPreferrdeLocations()
得到partition
的优先位置,由于一个partition
对应一个Task
,此partition
的优先位置就是task
的优先位置,
对于要提交到TaskScheduler
的TaskSet
中的每一个Task
,该ask
优先位置与其对应的partition
对应的优先位置一致。
从调度队列中拿到TaskSetManager
后,那么接下来的工作就是TaskSetManager
按照一定的规则一个个取出task
给TaskScheduler
,TaskScheduler
再交给SchedulerBackend
去发到Executor
上执行。前面也提到,TaskSetManager
封装了一个Stage
的所有Task
,并负责管理调度这些Task
。
根据每个Task
的优先位置,确定Task
的Locality
级别,Locality
一共有五种,优先级由高到低顺序:
名称 | 解析 |
---|---|
PROCESS_LOCAL | 进程本地化,task和数据在同一个Executor中,性能最好。 |
NODE_LOCAL | 节点本地化,task和数据在同一个节点中,但是task和数据不在同一个Executor中,数据需要在进程间进行传输。 |
RACK_LOCAL | 机架本地化,task和数据在同一个机架的两个节点上,数据需要通过网络在节点之间进行传输。 |
NO_PREF | 对于task来说,从哪里获取都一样,没有好坏之分。 |
ANY | task和数据可以在集群的任何地方,而且不在一个机架中,性能最差。 |
在调度执行时,Spark 调度总是会尽量让每个task
以最高的本地性级别来启动,当一个task
以本地性级别启动,但是该本地性级别对应的所有节点都没有空闲资源而启动失败,此时并不会马上降低本地性级别启动而是在某个时间长度内再次以本地性级别来启动该task
,若超过限时时间则降级启动,去尝试下一个本地性级别,依次类推。
可以通过调大每个类别的最大容忍延迟时间,在等待阶段对应的Executor
可能就会有相应的资源去执行此task
,这就在在一定程度上提升了运行性能。