1.Spark的【任务执行流程】|【运行流程】|【任务调度流程】
1)构建 Spark Application 的运行环境,也就是在Driver中创建SparkContext,同时构建DAGScheduler和TaskScheduler
2)SparkContext 向 Cluster Manager 注册,并申请运行 Executor 资源。
3)Cluster Manager 为 Executor 分配资源并启动 Executor 进程,Executor 运行情况将随着“心跳”发送到 Cluster Manager 上
4)SparkContext根据RDD的依赖关系构建DAG图,构建完毕后,将DAG图提交给DAGScheduler,DAGScheduler开始划分Stage,并将Stage以的TaskSet形式发送给TaskScheduler
5)Executor向SparkContext申请Task,TaskScheduler将Task发送给exector运行,同时SparkContext将应用程序代码发送给Exector
6)Execuotr将Task放入线程池中运行,把执行结果反馈给 Task Scheduler,然后再反馈给 DAG Scheduler。运行完毕后写入数据,SparkContext 向 ClusterManager 注销并释放所有资源
DAG 有向⽆环图(数据执⾏过程,有⽅法,⽆闭环)
DAG描述多个RDD的转换过程,任务执⾏时,可以按照DAG的描述,执⾏真正的计算(数据被操作的⼀个过程)
DAG是有边界的:开始(通过SparkContext创建的RDD),结束(触发Action,调⽤run Job就是⼀个完整的DAG就形成了,⼀旦触发Action就形成了⼀个完整的DAG)
⼀个RDD只是描述了数据计算过程中的⼀个环节,⽽DGA由⼀到多个RDD组成,描述了数据计算过程中的所有环节(过程)
⼀个Spark Application中是有多少个DAG:⼀到多个(取决于触发了多少次Action)
⼀个DAG中可能有产⽣多种不同类型和功能的Task,会有不同的阶段
DAGScheduler:将⼀个DAG切分成⼀到多个Stage,DAGScheduler切分的依据是Shuffle(宽依赖)
为什么要切分Stage?
⼀个复杂的业务逻辑(将多台机器上具有相同属性的数据聚合到⼀台机器上:shuffle)
如果有shuffle,那么就意味着前⾯阶段产⽣的结果后,才能执⾏下⼀个阶段,下⼀个阶段的计算要依赖上⼀个阶段的数据。
在同⼀个Stage中,会有多个算⼦,可以合并在⼀起,我们称其为pipeline(流⽔线:严格按照流程、顺序执⾏)
宽依赖和窄依赖⼀般来说普通的join都是宽依赖 rdd的特殊jion
stage过程,3个stage 6 个Task ⼀个stage有两个分区就有两个Task,⼀个Application有很多job,job划分依据run job⾏动算⼦,调⽤了⼏次就有⼏个job ,stage划分是依据suffle
来的,相同的过程划分到同⼀个stage,产⽣shuffle的阶段⼀份为⼆。
Spark总体架构
Spark 运行架构如图 1 所示,包括集群资源管理器(Cluster Manager)、多个运行作业任务的工作结点(Worker Node)、每个应用的任务控制结点(Driver)和每个工作结点上负责具体任务的执行进程(Executor)。
Driver 是运行 Spark Applicaion 的 main() 函数,它会创建 SparkContext。SparkContext 负责和 Cluster Manager 通信,进行资源申请、任务分配和监控等。
Cluster Manager 负责申请和管理在 Worker Node 上运行应用所需的资源,目前包括 Spark 原生的 Cluster Manager、Mesos Cluster Manager 和 Hadoop YARN Cluster Manager。
Executor 是 Application 运行在 Worker Node 上的一个进程,负责运行 Task(任务),并且负责将数据存在内存或者磁盘上,每个 Application 都有各自独立的一批 Executor。每个 Executor 则包含了一定数量的资源来运行分配给它的任务。
每个 Worker Node 上的 Executor 服务于不同的 Application,它们之间是不可以共享数据的。与 MapReduce 计算框架相比,Spark 采用的 Executor 具有两大优势。
∙ Executor 利用多线程来执行具体任务,相比 MapReduce 的进程模型,使用的资源和启动开销要小很多。
∙ Executor 中有一个 BlockManager 存储模块,会将内存和磁盘共同作为存储设备,当需要多轮迭代计算的时候,可以将中间结果存储到这个存储模块里,供下次需要时直接使用,而不需要从磁盘中读取,从而有效减少 I/O 开销,在交互式查询场景下,可以预先将数据缓存到 BlockManager 存储模块上,从而提高读写 I/O 性能。
Spark作业调度
可以根据spark.scheduler.mode 来设置FIFO or FAIR,默认的是FIFO模式
FIFO调度策略
Spark默认使用FIFO调度策略,先进先出,谁先提交谁先执行,后面的任务需要等待前面的任务执行。实现默认的SchedulerableBuilder⽅法,建⽴的调度池也为空,addTasksetmaneger也是调⽤默认的
不过从Spark 0.8开始,为了能支持各个作业间的公平调度,Spark提供了FAIR调度策略。
FAIR调度策略
1.先⽐较两个Stage的 Runningtask使⽤的核数,可以理解为Task的数量,谁⼩谁的优先级⾼;
2.⽐较两个Stage的 RunningTask 权重,谁的权重⼤谁先执⾏;
3.如果前⾯都⼀直,则⽐较名字了(字符串⽐较),谁⼤谁先执⾏;