本篇文章主要介绍:
- Spark的基本概念
- Spark的内核架构,详细介绍从Saprk程序编写完成使用Spark submit(shell)的方式提交到完成任务的流程
- Spark在不同集群中的运行架构
1. Spark的内核架构
Spark任务详解:
-
将编写的Spark程序打成 jar 包
-
调用 spark-submit 脚本提交任务到集群上运行
-
运行sparkSubmit的main方法,在这个方法中通过反射的方式创建我们编写的主类的实例对象,然后调用main方法,开始执行我们的代码(我们的spark程序中的driver就运行在sparkSubmit进程中)
-
当代码运行到创建 SparkContext 对象时,那就开始初始化 SparkContext 对象了
-
在初始化 SparkContext 对象的时候,会创建两个特别重要的对象,分别是:DAGScheduler 和 TaskScheduler
DAGScheduler的作用:将RDD的依赖切分成一个一个的stage,然后将stage作为taskSet提交给DriverActor
-
在构建 TaskScheduler 的同时,会创建两个非常重要的对象,分别是 DriverActor 和 ClientActor
ClientActor的作用:向master注册用户提交的任务
DriverActor的作用:接受executor的反向注册,将任务提交给executor -
当 ClientActor 启动后,会将用户提交的任务和相关的参数封装到 ApplicationDescription 对象中,然后提交给 Maseter 进行任务的注册
-
当 Maseter 接受到 ClientActor 提交的任务请求时,会将请求参数进行解析,并封装成 Application,然后将其持久化,然后将其加入到任务队列 waitingApps 中
-
当轮到我们提交的任务运行时,就开始调用 schedule(),进行任务资源的调度
-
Maseter 将调度好的资源封装到 launchExecutor 中发送给指定的worker
-
worker接受到 Maseter 发送来的 launchExecutor 时,会将其解压并封装到 ExecutorRunner 中,然后调用这个对象的start(), 启动Executor
-
Executor 启动后会向 DriverActor 进行反向注册
-
DriverActor 会发送注册成功的消息给 Executor
-
Executor 接受到 DriverActor 注册成功的消息后会创建一个线程池,用于执行 DriverActor 发送过来的task任务
-
当属于这个任务的所有的Executor启动并反向注册成功后,就意味着运行这个任务的环境已经准备好了,Driver 会结束SparkContext 对象的初始化,也就意味着new SparkContext 这句代码运行完成
-
当初始化 SparkContext 成功后,Driver 端就会继续运行我们编写的代码,然后开始创建初始的RDD,然后进行一系列转换操作,当遇到一个action算子时,也就意味着触发了一个job
-
Driver 会将这个job提交给 DAGScheduler
-
DAGScheduler 将接受到的job,从最后一个算子向前推导,将DAG依据宽依赖划分成一个一个的 stage,然后将 stage 封装成 TaskSet,并将 TaskSet 中的 task 提交给 DriverActor
-
DriverActor 接受到 DAGScheduler 发送过来的task,会拿到一个序列化器,对 task 进行序列化,然后将序列化好的task封装到 launchTask 中,然后将 launchTask 发送给指定的 Executor
-
Executor 接受到了 DriverActor 发送过来的 launchTask 时,会拿到一个反序列化器,对 launchTask 进行反序列化,封装到 TaskRunner 中,然后从 Executor 这个线程池中获取一个线程,将反序列化好的任务中的算子作用在RDD对应的分区上
2. Spark中的基本概念
-
Application:表示你的应用程序
-
Driver:表示 main() 函数,创建 SparkContext。由 SparkContext 负责与 ClusterManager 通信,进行资源的申请,任务的分配和监控等。程序执行完毕后关闭SparkContext
-
Executor:某个 Application 运行在 Worker 节点上的一个进程,该进程负责运行某些 Task ,并且负责将数据存在内存或者磁盘上。在 Spark on Yarn 模式下,其进程名称为 CoarseGrainedExecutor Backend,一个 CoarseGrainedExecutor Backend 进程有且仅有一个 executor 对象,它负责将 Task 包装成 TaskRunner,并从线程池中抽取出一个空闲线程运行 Task,这样,每个CoarseGrainedExecutorBackend 能并行运行Task的数据就取决于分配给它的CPU的个数。
-
Worker:集群中可以运行 Application 代码的节点。在 Standalone 模式中指的是通过 slave 文件配置的 worker 节点,在Spark on Yarn 模式中指的就是 NodeManager 节点。
-
Task:在 Executor 进程中执行任务的工作单元,多个 Task 组成一个 Stage
-
Job:包含多个 Task 组成的并行计算,是由 Action 行为触发的
-
Stage:每个 Job 会被拆分很多组 Task,作为一个 TaskSet,其名称为Stage
-
DAGScheduler:根据 Job 构建基于 Stage 的 DAG,并提交 Stage 给 TaskScheduler,其划分 Stage 的依据是 RDD 之间的依赖关系
-
TaskScheduler:将 TaskSet 提交给 Worker(集群)运行,每个 Executor 运行什么 Task 就是在此处分配的。
2.1 DAGScheduler
Job=多个Stage,Stage=多个同种 Task, Task 分为 ShuffleMapTask 和 ResultTask,Dependency 分为 ShuffleDependency 和 NarrowDependency
面向 Stage的切分,切分依据为宽依赖
维护 waiting jobs 和 active jobs,维护 waiting stages、active stages 和 failed stages,以及与 jobs 的映射关系
主要职能:
-
生成一个Stage并提交,判断Stage是否有父Stage未完成,若有,提交并等待父Stage
DAGScheduler 里增加了一些 waiting stage 和一个 running stage
running stage 提交后,分析stage里Task的类型,生成一个Task描述,即TaskSet
调用 TaskScheduler.submitTask(taskSet, …)方法,把Task描述提交给TaskScheduler
TaskScheduler依据资源量和触发分配条件,会为这个TaskSet分配资源并触发执行。
DAGScheduler提交job后,异步返回JobWaiter对象,能够返回job运行状态,能够cancel job,执行成功后会处理并返回结果
-
处理TaskCompletionEvent
-
其他与job相关的操作还包括:cancel job, cancel stage, resubmit failed stage等
2.2 TaskScheduler
维护 task 和 executor 对应关系,executor 和物理资源对应关系,在排队的 task 和正在跑的task。
内部维护一个任务队列,根据 FIFO 或 Fair 策略,调度任务。
TaskSchedule r本身是个接口,spark里只实现了一个 TaskSchedulerImpl,理论上任务调度可以定制。
主要职能:
-
submitTasks(taskSet),接收DAGScheduler提交来的tasks
为tasks创建一个TaskSetManager,添加到任务队列里。TaskSetManager跟踪每个task的执行状况,维护了task的许多具体信息
-
cancelTasks(stageId),取消一个stage的tasks
-
worker offers资源列表进行随机洗牌,按照进程本地化、worker本地化、机器本地化、机架本地化的优先级顺序,为每个taskSet提供可用的cpu核数
2.3 Executor
Executor 是 spark 里的进程模型,可以套用到不同的资源管理系统上,与 SchedulerBackend 配合使用。
内部有个线程池,有个running tasks map,有个actor,接收上面提到的由SchedulerBackend发来的事件。
事件处理
- launchTask:根据task描述,生成一个 TaskRunner 线程,丢尽 running tasks map 里,用线程池执行这个 TaskRunner
- killTask:从running tasks map里拿出线程对象,调它的kill方法。
3. Spark在不同集群中的运行架构
3.1 Spark on Standalone
3.2 Spark on YARN
Spark on YARN模式根据Driver在集群中的位置分为两种模式:一种是YARN-Client模式,另一种是YARN-Cluster
YARN-Client
Yarn-Client模式中,Driver在客户端本地运行,这种模式可以使得Spark Application和客户端进行交互,因为Driver在客户端,所以可以通过webUI访问Driver的状态
YARN-Cluster
在YARN-Cluster模式中,当用户向YARN中提交一个应用程序后,YARN将分两个阶段运行该应用程序:第一个阶段是把Spark的Driver作为一个ApplicationMaster在YARN集群中先启动;第二个阶段是由ApplicationMaster创建应用程序,然后为它向ResourceManager申请资源,并启动Executor来运行Task,同时监控它的整个运行过程,直到运行完成。
YARN-Client 与 YARN-Cluster 区别:
- YARN-Cluster模式下,Driver运行在AM(Application Master)中,它负责向YARN申请资源,并监督作业的运行状况。当用户提交了作业之后,就可以关掉Client,作业会继续在YARN上运行,因而YARN-Cluster模式不适合运行交互类型的作业;
- YARN-Client模式下,Application Master仅仅向YARN请求Executor,Client会和请求的Container通信来调度他们工作,也就是说Client不能离开。
一般来说,YARN-Cluster 用于生产,YARN-Client 用于调试
参考:
https://blog.csdn.net/qq_37142346/article/details/81204921
https://blog.csdn.net/li17610380561/article/details/80131242
https://www.cnblogs.com/qingyunzong/p/8945933.html