Spark调度模型

*爱你&永不变心* 提交于 2020-03-02 18:19:25

调度模型的好坏,是由底层的抽象模型所决定的,spark的底层抽象是RDD

spark调度模型系统,分为底层调度模型(TASKscheduler)和高层调度模型(DAGscheduler)

 调度过程

1. application driver发出请求,这个application首先创建sparkconf和sparkcontext对象,在sc对象中TASKscheduler,DAGscheduler以及schedulerbackend对象,向master注册当前程序并申请计算资源(注意,如果底层是用yarn来进行资源管理和调度,那么会向yarn resource manager去申请计算资源,standalone模式下,具体的实现是taskschedulerimpl来完成的)

2. 这时候master会根据当前它掌握的worker的资源并通过心跳看worker是不是存活的),为application分配appid和计算资源,并通知对应的worker按需求启动executor

分配计算资源的依据,来自spark-env.sh,default.sh,spark-submit的参数,和程序中sparkConf配置的参数

worker机器上会生成一个worker进程,通过一个proxy启动executorbackend进程,这个进程会启动executor,以及里面的线程池

3. 然后driver 根据action 会提交runjob代码,触发job,这时候,sc会通过DAGscheduler 把job中一系列的RDD变成一个DAG有向无环图

一般来说一个action对应了一个job,但是也有application对应多个job的情况,比如checkpoint会触发job,rangepatition会触发job等

driver有2种运行模式,一种是从client,一种是从cluster集群内部

4. 这时候DAGscheduler接手,输入是DAG有向无环图,输出给TASKscheduler是若干task set

根据系统RDD溯源从后往前推,去找parentjob,根据宽窄依赖,DAGscheduler进行stage的划分,在stage内部是业务逻辑完全相同,数据不同,没有shuffle,只有pipeline,速度很快

窄依赖就是一对一或者多对一,宽依赖就是shuffle,一对多)

注意,DAGscheduler 会根据是否进行了shuffle来进行stage的划分,stage有2种,一种是产生结果的,叫做resultstage,对应了action操作,还有一种是shufflemapstage,对应了trasformation操作

在stage内部的pipeline,没有监听,速度非常快,stage之间有监听,有数据交换,会在本地完成数据的固话,并告诉shuffle manager,上一个stage的保存数据在哪里,因为这个stage需要进行shuffle,需要从其他的worker节点读取数据

shuffle就是从其它节点抓数据,会产生网络传输,和带来磁盘IO

 

5. 将task set提交给底层调度模型(TASKscheduler和schedulerbackend,他们负责具体任务的task的运行)拿到tast set任务集,并分割为多个task,会根据数据本地性,把task代码和lib发送到合适的多个executor上去执行(taskscheduler会负责确定task在哪个executor上面执行最佳,并在执行前,通过schedulerbackend获取了这个executor)

这里的具体实现是,TASKscheduler会将各个task通过actor的方式进行广播给各个worker,在worker的executor中的线程池会真正执行task,在worker上面有blockmanager,会管理数据的存放方式,是在磁盘还是在内存中

task有2种,在最后一个stage的task,会产生job的结果,叫resultTask,

之前的stage的task,叫shuffleMapTask,为下一个stage的计算做数据准备

每个executor会计算RDD中的一个partition(一部分RDD),在该partition上来具体执行我们定义的一系列同一个stage内部的函数,以此类推

stage之间是串行的,stage内部是并行的

容错

1. 基于血统的RDD容错

当某个rdd失败,可以从最近的persist点或者stage完结点,也就是shuffle点开始回复,进行pipeline的计算, 比如rdd900出错了,那么回溯如果899是成功的,就再计算899到900,而不需要重头计算

2. 如果任务task出错

任务会进行一定次数的重试,

3. 如果stage出错

也会进行一定次数的重试,当然stage的重试会尽量使用已经计算完毕的task的结果

 

spark和hadoop的底层调度比较

worker用于管理当前节点的内存cpu资源使用情况,它会接受cluster manager/master的资源请求,并会通过executorrunner来启动一个executor的新线程,然后executor会启动一个jvm,并由其中的线程池的线程来具体完成task

 一个worker默认情况下为当前应用开辟一个executor,这个数目可以配置

如果executor坏掉,worker会向master主动汇报,但是不是通过心跳,心跳只返回给master一个workerid

对于hadoop,采用一个任务对应一个jvm进程的方式,并且jvm不可复用

 

为什么快

RDD的lazy机制决定了只有在真正计算的时候,也就是action触发job的时候,才会计算,所以在此之前,是没有计算产生的,也就没有中间结果产生

如果有100个RDD的transformation操作,那么hadoop会产生999个中间结果并将其存放到磁盘,这个太耗时了,相反,spark在内存中进行迭代计算就完成了,没有中间结果

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!