Spark两种运行流程
SparkOnYarn(cluster)
1.由客户端向ResourceManager提交请求,上传jar包和配置参数到RM分配的HDFS路径
2.ResuurceManager向NodeManager申请资源,创建Spark ApplicationMaster(每一个SparkContext都有一个appmaster)
3.NM启动ApplicationMaster,并向RMMaster注册
4.ApplicationMaster找到HDFS中的文件,启动SparkContext、DAGScheduler和和YARN Cluster Scheduler
5.RS向RSM注册申请container(comtainer有两种,一种是RS向RSM申请,运行在appmaster中,可唯一指定applicationMaster所需资源,另一种是applicationMaster向RM申请,由RM资源调度器异步分配给appmaster,运行在各个任务上)
6.RM通知NM分配Container(每个Container对应一个executor)
7.Spark ApplicationMaster直接和Container(executor)进行交互,完成分布式任务
8.程序运行完后applicationMaster向RM注销自己
cluster模式下driver运行在集群中,其实是在ApplicationMaster这个进程中
SparkStandalone
1.Spark-submit提交任务,调用spark-submit.sh,启动spark-class,SparkSubmit的main方法被启动,然后反射启动程序main方法,创建SparkContext,SparkContext创建完成后会创建出SparkEnv,DAGscheduler,TaskScheduler,StandaloneSchedulerBackend
2.StandaloneSchedulerBackend调用StandaloneAppClient创建出来ClientEndPoint,调用父类的start方法创建DriverEndPoint
3.ClientEndPoint向master注册application,并封装启动executor的命令
4.master收到来自client端的app注册请求后,回去遍历自己的worker列表,找出有空闲资源的worker,然后为ec分配资源,通知worker启动executor
5.响应driver注册成功
6.worker根据指令启动ec,ec会向driverEndpoint注册并保持通信,driverEndpoint返回注册成功的消息,然后会创建出线程池,等待task提交过来运行。
7.程序解析业务代码,创建DAG,当碰到action算子的时候,DAG创建完成,此时回去真正划分stage,提交task
8.切分Stage过程:根据最后一个RDD创建一个finalStage,从后往前遍历,获取其父RDD的依赖关系,如果是窄依赖,则将父rdd压入栈中,如果是宽依赖,则创建一个shuffleMapStage,指导所有的RDD都遍历完毕
9.划分完stage后则要进行提交,具体的提交逻辑是,根据当前stage获取父stage,如果父stage为空,则当前stage为起始stage,交给submitmissingtask处理,否则,递归调用submitstage进行提交
10.DAGscheduler将job划分成由stage组成的DAG之后,会根据Stage的类型生成ShuffleMapTask和ResultTask,然后使用taskset进行封装,最后调用taskscheduler的submitTasks方法进行提交,而实际上是调用TaskSchedulerImpl的submitTasks方法。进入backend的reviveOffers()方法,给DriverEndpoint发送了一条ReviveOffers消息。Driver收到消息后调用makeOffers()方法,进行资源分配,最后调用launchTask方法将task提交到executor上
11.接受到task之后进行反序列化,用taskRunner线程来封装每一个task,然后将其扔到executor线程池中,一旦有资源,线程就会运行,调用taskRunner的run方法,最终调用task的runTask方法。
浙公网安备 33010602011771号