Lineage
RDD只支持粗粒度转换,即在大量记录上执行的单个操作。将创建RDD的一系列关系(称为Lineage,血缘)记录下来,以便恢复丢失的分区。
RDD的血缘会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,他可以根据这些信息来重新运算,以恢复丢失的数据分区。
image.png例如:
val inputRdd = sc.parallelize(Array(1, 2, 3, 4, 5, 6))
val mapRdd = inputRdd.map((_, 1))
val reduceRdd = mapRdd.reduceByKey(_ + _)
println(reduceRdd.toDebugString)
/*
输出结果为:
(4) ShuffledRDD[2] at reduceByKey at LineageDemo.scala:11 []
+-(4) MapPartitionsRDD[1] at map at LineageDemo.scala:10 []
| ParallelCollectionRDD[0] at parallelize at LineageDemo.scala:9 []
*/
println(reduceRdd.dependencies)
/*
输出结果为:
List(org.apache.spark.ShuffleDependency@6145b81e)
*/
通过toDebugString
方法我们可以得到RDD转换行为的依赖关系,通过dependencies
参数可以得到RDD依赖关系的列表。
其中RDD和父RDD间的依赖分为两种,窄依赖(Narrow Dependency)和宽依赖(Wide Dependency)。
窄依赖
窄依赖指一个父RDD的分区数据最多被子RDD的一个分区使用。
image.png宽依赖
宽依赖指多个RDD的分区会依赖同一个父RDD分区,会引起shuffle。
image.pngDAG
DAG(Direct Acyclic Graph)称为有向无环图,原始的RDD通过一系列的转换形成DAG,根据RDD间的依赖关系不同,将DAG划分为不同的Stage。
对于窄依赖,分区的转换操作在同一Stage中完成计算;而对于宽依赖,由于有Shuffle的存在,只能当父RDD完成计算后,才能开始下一步的计算,所以宽依赖是划分Stage的依据。
任务划分
RDD的任务分为:Application、Job、Stage和Task。
1)Application:初始化一个SparkContext即生成一个Application
2)Job:一个行动算子会生成一个Job
3)Stage:根据RDD间依赖关系的不同,将Job划分为不同的Stage,每有一个宽依赖就会划分一个Stage
4)Task:Stage是一个TaskSet,将Stage划分的结果发送到不同Executor执行即为一个Task
网友评论