这是Spark官方给的图,大致意思就是:
四个步骤
1.构建DAG(有向无环图)(调用RDD上的方法)
2.DAGScheduler将DAG切分Stage(切分的依据是Shuffle),将Stage中生成的Task以TaskSet的形式给TaskScheduler
3.TaskScheduler调度Task(根据资源情况将Task调度到相应的Executor中)
4.Executor接收Task,然后将Task丢入到线程池中执行
DAG 有向无环图(数据执行过程,有方法,无闭环)
虽然是程序的起点和终点都是hdfs,但是不是同一个文件,如果图中的out文件存在的话就会报错。
DAG描述多个RDD的转换过程,任务执行时,可以按照DAG的描述,执行真正的计算(数据被操作的一个过程)
DAG是有边界的:开始(通过SparkContext创建的RDD),结束(触发Action,调用run Job就是一个完整的DAG)
一个RDD只是描述了数据计算过程中的一个环节,而DAG由一到多个RDD组成,描述了数据计算过程中的所有环节(过程)
一个Spark Application中是有多少个DAG:一到多个(取决于触发了多少次Action)
为什么要切分Stage?
一个复杂的业务逻辑(将多台机器上具有相同属性的数据聚合到一台机器上:shuffle)
如果有shuffle,那么就意味着前面阶段产生的结果后,才能执行下一个阶段,下一个阶段的计算要依赖上一个阶段的数据。
在同一个Stage中,会有多个算子,可以合并在一起,我们称其为pipeline(流水线:严格按照流程、顺序执行)
Spark运行时,首先启动一个客户端(Driver),也可以时spark-shell客户端
spark-submit --master spark://hadoop-master:7077 --executor-memory 4g --total-executor-cores 12
1,客户端和Master建立链接并且申请资源,每个executor需要4g内存,总共需要12核
2,master进行资源调度(节点向master注册的时候,会将自己的资源情况一并提交给master)
3,master和worker进行RPC通信,启动executor
4,启动各个worker节点上的executor
5,executor和Driver端进行通信
6,RDD触发Action后,会根据最后这个RDD往前推断依赖关系(宽依赖或者窄依赖),遇到Shuffle就切分Stage,会递归切分,递归的出口是RDD没有父RDD
7,DAGScheduler切分完Stage后,会进行提交Stage,先提交前面的Stage,前面的Stage执行完之后再提交后面的Stage,每一个stage都会产生很多业务逻辑相同的Task,然后以TaskSet的形式将task传递给TaskScheduler,然后TaskScheduler将Task进行序列化,根据资源情况,将task发送给Executor
8,将Driver端产生的task发送给executor
9,executor在接收到task之后,先将task进行反序列化,然后将task用一个实现了runnable接口的实现类包装起来,然后将该包装类丢入线程池,包装类实现的run方法就会被执行,进而调用task的计算逻辑。
以上就是Spark的执行流程。