Spark执行流程

启动流程   

    我们写的spark程序,打成jar包,用spark-submit来提交;
    local模式:当我们的程序提交到集群上时,会加载并执行我们的jar包,并找到jar包中的main函数执行一遍,执行main函数所启动的这个进程名就是SparkSubmit,这个进程就是我们所说的Driver进程;
     cluster模式:会在集群中找到一台node,启动一个进程执行一遍我们提交的代码,这个进程就是Driver。Driver运行Application的main()函数,创建SparkContext(整个应用的上下文,控制应用的生命周期)对象。代码从main函数开始执行,new SparkConf()设置我们运行Spark时的环境参数(还可以通过spark-submit --加上参数来设置),new SparkContext(),创建DAGScheduler和TaskScheduler,TaskScheduler另启动一个线程将Application注册到Master中(是放到Master中的ArrayBuffer的数据结构中,当ArrayBuffer中有信息之后,Master会调用自己的scheduler()方法,scheduler会为当前的Application申请资源,此时master会找一些空闲的Worker,并在Worker上启动Executor进程,Executor启动完成之后会反向注册给TaskScheduler)现在Application有了资源后,开始进行任务的调度。

调度流程

    Spark算子分为以下三类:Action算子,控制算子,转换算子。其中控制算子和转换算子都是懒执行的,只有Action算子才会出发计算操作。

    1.Action类型的算子触发job的执行。源码中调用了SparkContext的runJob()方法,根进源码发现底层调用的是DAGScheduler的runJob()方法。

    2.DAGScheduler会将我们的job按照宽窄依赖划分为一个个stage(每个stage根据RDD的Partition的个数决定task的个数),每个stage中有一组并行计算的task,每一个task都可以看做是一个pipeline,这个管道里面数据是一条一条被计算的,每经过一个RDD会经过一次处理,RDD是一个抽象的概念里面存储的是一些计算的逻辑,每一条数据计算完成之后会在shuffle write过程中将数据落地写入我们的磁盘中。

    3.stage划分完之后会以TaskSet的形式提交给我们的TaskScheduler。源码中TaskScheduler.submit.tasks(new TaskSet())只是一个调用方法的过程而已。我们口述说是发送到TaskScheduler。TaskScheduler接收到TaskSet之后会进行遍历,每遍历一条调用launchTask()方法,launchTask()根据数据本地化的算法发送task到指定的Executor中执行。task在发送到Executor之前首先进行序列化,Executor中有ThreadPool,ThreadPool中有很多线程,在这里面来具体执行我们的task。

    4.TaskScheduler和Executor之间有通信(Executor有一个邮箱(消息循环体CoresExecutorGraintedBackend)),Executor接收到task后首先将task反序列化,反序列化后将这个task变为taskRunner(new taskRunner),并不是TaskScheduler直接向Executor发送了一个线程,这个线程是在Executor中变成的。然后这个线程就可以在Executor中的ThreadPool中执行了。

    5.Executor接收到的task分为map task和reduce task,比如这里有三个stage,先从stage1到stage2再到stage3,针对于stage2来说,stage1中的task就是map task,stage2中的task就是reduce task,针对于stage3来说。。(map task是一个管道,管道的计算结果会在shuffle write阶段数据落地,数据落地会根据我们的分区策略写入不同的磁盘小文件中,注意相同的key一定写入到相同的磁盘小文件中),map端执行完成之后,会向Driver中的DAGScheduler对象里面的MapOutPutTracker发送一个map task的执行状态(成功还是失败还有每一个小文件的地址)。然后reduce task开始执行,reduce端的输入数据就是map端的输出数据。那么如何拿到map端输出数据呢?reduce task会先向Driver中MapOutPutTracker请求这一批磁盘小文件的地址,拿到地址后,由reduce task所在的Executor里面的BlockManager向Map task所在的Executor先建立连接,连接是由ConnectionManager负责的,然后由BlockTransformService去拉取数据,拉取到的数据作为reduce task的输入数据(如果使用到了广播变量,reduce task或者map task它会先向它所在的Executor中的BlockManager要广播变量,没有的话,本地的BlockManager会去连接Driver中的BlockManagerMaster,连接完成之后由BlockTransformService将广播变量拉取过来)Executor中有了广播变量了,task就可以正常执行了。

名词解析

ClusterManager:在Standalone模式中即为Master(主节点),控制整个集群,监控Worker,在YARN模式中为资源管理器(SourceManager)。

Worker:从节点,负责控制计算节点,启动Executor,在YARN模式中为NodeManager,负责计算节点的控制。

Driver:运行Application的main()函数并创建SparkContext。

Executor:执行器,在worker node上执行任务的组件,用于启动线程池运行任务,每个Application拥有独立的一组Executors。

SparkContext:整个应用的上下文,控制应用的生命周期。

RDD:Spark的基本计算单元,一组RDD可形成执行的有向五环图RDD Graph.

DAG Scheduler:实现将Spark作业分解成一到多个Stage,每个Stage根据RDD的Partition个数决定Task的个数,然后生成相应的Task set放到TaskScheduler中。

TaskScheduler:将任务(Task)分发给Executor(在这里Executor是一个进程,task是Executor进程中的一个线程)执行。

Stage:一个Spark作业一般包含一到多个Stage。

Task:一个Stage包含一到多个Task,通过多个Task实现并行运行的功能。

Transformations:转换(如:map,filter,groupBy,join等),Transformations操作是lazy的,也就是说从一个RDD转换生成另一个RDD的操作不是马上执行,Spark在遇到Transformations操作时只会记录需要这样的操作,并不会去执行,需要等到有Actions操作的时候才会真正启动计算过程进行计算。

Actions:操作(如:count,collect,save等),Actions操作会返回结果或把RDD数据写到存储系统中。Actions是触发Spark启动计算的动因。

SparkEnv:线程级别的上下文,存储运行时重要组件的引用,SparkEnv内创建并包含如下一些重要组件的引用。

1>MapOutPutTracker:负责Shuffle元信息的存储。

2>BroadcastManager:负责广播变量的控制与元信息的存储。

3>BlockManager:负责存储管理,创建和查找块。

4>MetricsSystem:监控运行时性能指标信息。

5>SparkConf:负责存储配置信息。

文章持续更新
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值