被百度大佬深深折服,回头重新复习一遍spark
少年阿宏版超详细理解spark任务执行的过程,不喜勿喷
Driver就是我们写的spark程序,打成jar包后通过spark-submit来提交.-------少年阿宏
standalone模式下:
driver进程启动后,首先会构建sparkcontext,sparkcontext主要包含两部分:DAGScheduler和 TaskScheduler,然后TaskScheduler会寻找集群资源管理器(Master/Worker)的Master节点,Master节点接收到ApplicationMaster的注册请求后,通过资源调度算法,在自己的集群的worker上启动Executor进程,启动的executor也会反向注册到TaskScheduler(SchedulerBackend)上.Driver等待资源满足,执行main函数,Spark的查询为懒执行,当执行到 action 算子时才开始真正执行,开始反向推算,一个Action算子触发一个job,并交给DAGScheduler来处理.
DAGScheduler主要做两个部分的事情:
①将1个job切分成多个stage.DAGScheduler会根据RDD的血缘关系构成的DAG从后往前,由最终的RDD不断通过依赖回溯判断父依赖是否是宽依赖,遇到一个shuffle就划分一个Stage,将一个Job划分为若干Stages.无shuffle的称为窄依赖,窄依赖之间的RDD被划分到同一个Stage中。划分的Stages分两类,一类叫做ResultStage,为DAG最下游的Stage,由Action方法决定,另一类叫做ShuffleMapStage,为下游Stage准备数据。
②将stage打包成Taskset提交.一个Stage如果没有父Stage,那么从该Stage开始提交,父Stage执行完毕才能提交子Stage。Stage提交时会将Task信息(分区信息以及方法等 一个Partition对应一个Task)序列化并被打包成TaskSet交给TaskScheduler,,另一方面TaskScheduler会监控Stage的运行状态,只有Executor丢失或者Task由于Fetch失败才需要重新提交失败的Stage以调度运行失败的任务,其他类型的Task失败会在TaskScheduler的调度过程中重试。
TaskScheduler.TaskScheduler将接收的TaskSet封装为TaskSetManager(一对一)加入到调度队列中。一个TaskSet含有n多个task信息,这些task都是同一个stage的。TaskScheduler初始化后会启动SchedulerBackend,它负责跟外界打交道,接收Executor的注册信息,并维护Executor的状态.SchedulerBackend监控到有资源后,会询问TaskScheduler有没有任务要运行,TaskScheduler会从调度队列中按照指定的调度策略选择TaskSetManager去调度运行。TaskSetManager按照一定的调度规则一个个取出task给TaskScheduler,TaskScheduler再交给SchedulerBackend去发到Executor上执行。Task被提交到Executor启动执行.Executor进程内部会维护一个线程池,Executor每接收到一个task,都会用TaskRunner封装task,然后从线程池中取出一个线程去执行taskTaskRunner主要包含两种task:ShuffleMapTask和ResultTask,除了最后一个stage是ResultTask外,其他的stage都是ShuffleMapTask.Executor会将执行状态上报给SchedulerBackend,SchedulerBackend则告诉TaskScheduler,TaskScheduler找到该Task对应的TaskSetManager,并通知到该TaskSetManager.这样TaskSetManager就知道Task的运行状态.对于运行失败的Task,TaskSetManager会记录它失败的次数,如果失败次数还没有超过最大重试次数,那么就把它放回待调度的Task池子中等待重新执行,当重试次数过允许的最大次数,整个Application失败。在记录Task失败次数过程中,TaskSetManager还会记录它上一次失败所在的ExecutorId和Host,这样下次再调度这个Task时,会使用黑名单机制,避免它被调度到上一次失败的节点上,起到一定的容错作用。
yarn-client模式下:
在YARNClient模式下,Driver在任务提交的本地机器上运行,Driver会向ResourceManager申请启动ApplicationMaster,随后ResourceManager分配container,在合适的NodeManager上启动ApplicationMaster,此时的ApplicationMaster的功能相当于一个ExecutorLaucher,只负责向ResourceManager申请Executor内存。ResourceManager接到ApplicationMaster的资源申请后会分配container,然后ApplicationMaster在资源分配指定的NodeManager上启动Executor进程,Executor进程启动后会向Driver反向注册。另外一条线,Driver自身资源满足的情况下,Driver开始执行main函数,之后执行Action算子时,触发一个job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,Executor注册完成后,Driver将task分发到各个Executor上执行。(具体细节见上)
yarn-cluster模式下:
在 YARN Cluster 模式下,任务提交后会和 ResourceManager 通讯申请启动ApplicationMaster,随后 ResourceManager 分配 container,在合适的 NodeManager上启动 ApplicationMaster,此时的ApplicationMaster 就是 Driver。Driver 启动后向 ResourceManager 申请 Executor 内存,ResourceManager会分配container,然后在合适的 NodeManager 上启Executor 进程,Executor 进程启动后会向 Driver 反向注册。另外一条线,Driver自身资源满足的情况下,开始执行main函数,之后执行Action算子时,触发一个job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,Executor注册完成后,Driver将task分发到各个Executor上执行。—少年阿宏