首先了解几个阶段
Spark集群
- 一个spark集群可以并发运行多个spark应用。
Spark应用
- 一个spark应用由一个driver(写逻辑代码)和多个executor线程组成。spark程序在driver端执行,发送指令到executor所在节点。
- 当启动sparkContext的时候,一个driver就被启动了,同时多个executor也被启动。executor不能跨节点,但是一个节点可以有多个executor。RDD会跨越多个executor进行并行计算,一个executor可以处理RDD多个分区的数据,但是一个分区的数据不能被多个executor执行。
- 一个spark应用可以并发运行多个job,触发一次action算子就是一次job。
Job
- spark RDD是懒执行,触发一次action,切分一个job。
- 一个job可以有多个阶段(stage)。
stage
- 一个宽依赖切分一个stage。
- stage的数量 = 宽依赖数量 + 1。
- 一个stage有多个task。
task
- task的数量 = 每个阶段最后一个RDD的分区数量。
通过web UI查看各阶段之间的关系
val conf: SparkConf = new SparkConf().setAppName(this.getClass.getName).setMaster("local[*]")
val sc = new SparkContext(conf)
val rdd: RDD[Int] = sc.makeRDD(List(1,3,4,5,1,3,9), 2)
val resRDD: RDD[(Int, Int)] = rdd.map((_,1)).reduceByKey(_+_)
// 第一次action
resRDD.foreach(println)
// 第二次action
resRDD.saveAsTextFile("D:\\develop\\workspace\\bigdata2021\\spark2021\\out")
Thread.sleep(100000000)
sc.stop()
查看job的数量(每一个action触发一次job)
查看job0的stage数量(每触发一次宽依赖增加一次stage的数量)
查看task的数量(每个stage最后阶段的RDD分区数)
如果存在shuffle过程
- 系统自动对shuffle之前的过程进行缓存,在web页面显示skipped。
Stage任务划分
-
首先生成DAG有向无环图,通过点和线组成的拓扑图形,该图形具有方向,不会形成闭环。
-
原始的RDD经过一系列的转换就形成了DAG,根据RDD之间的宽依赖关系将DAG分为不同的Stage。
-
DAG记录了RDD的转换过程和任务的阶段。
-
RDD任务切分中间过程分别为:Application-> job->stage->task.
-
启动sparkContext时就启动了Application。
-
一个action算子生成一个job。
-
每个job根据宽依赖切分为不同的stage。
-
每个stage最终RDD分区的数量就是task的数量。