一、RDD的依赖关系
RDD和它依赖的⽗RDD
(
s
)的关系有两种不同的类型,即窄依赖(
narrow dependency
)和宽依赖(
wide dependency)。
注:
使⽤代码
rdd.toDebugString 可
打印依赖关系
1.1窄依赖
说明
:
⽗
RDD
的每个分区只被⼀个⼦
RDD
分区使⽤⼀次
窄依赖有分为两种:
1)OneToOneDependency
即是⼀种是⼀对⼀的依赖,
2)RangeDependency
还有⼀个是范围的依赖 RangeDependency
,它仅仅被
org.apache.spark.rdd.UnionRDD
使⽤。
UnionRDD
是把多个RDD
合成⼀个
RDD
,这些
RDD
是被拼接⽽成,每个⽗
RDD
的
Partition
的相对顺序不会变,只不过每个⽗ RDD在
UnionRDD
中的
Partition
的起始位置不同
总结:窄依赖我们形象的比喻为独生子女
算⼦:
map
、
flatMap
、
mapPartition
、
filter
,
join(特殊)
等
1.2宽依赖
说明:宽依赖指的是多个⼦RDD的Partition会依赖同⼀个⽗RDD的Partition
总结:宽依赖我们形象的⽐喻为
超⽣
算⼦:
reduceByKey
、
groupBy
、
groupByKey
、
aggregateByKey
、
distinct,
join(特殊)
等
查看源码
可以发现⼀个问题
Dependency(
依赖
)
的意思
可以发现
ShuffleDependency
是其⼦类
(
即宽依赖
)
NarrowDependency
是其⼦类
(
即窄依赖
)
OneToOneDependency 继承NarrowDependency
RangeDependency继承NarrowDependency
注
:
宽依赖就会发⽣
shuffle
过程
二、Lineage(⾎统)&容错性
Lineage
RDD只⽀持粗粒度转换,即在⼤量记录上执⾏的单个操作。将创建
RDD
的⼀系列
Lineage
(即⾎统)记录下来,以便恢复丢失的分区。RDD
的
Lineage
会记录
RDD
的元数据信息和转换⾏为,当该
RDD
的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
- RDD的Lineage记录的是粗颗粒度的特定数据Transformation操作(如filter、map、join等)行为
- RDD在Lineage依赖方面分为两种:窄依赖(Narrow Dependencies)与宽依赖(Wide Dependencies。
- 容错原理:如果一个节点死机了,而且运算窄依赖,则只要把丢失的父RDD分区重算即可,不依赖于其他节点。而宽依赖需要父RDD的所有分区都存在,重算就很昂贵了。【在宽依赖处加Checkpoint更好的方法】
容错性
在Spark的容错机制中,当一个节点宕机了,进行容错恢复时,对于窄依赖来讲,进行重计算时只要把丢失的父RDD分区重算即可,不依赖于其他节点。而对于Shuffle Dependency来说,进行重计算时需要父RDD的分区都存在,这样计算量就太大了比较耗费性能。
比如上图程序运行到红线位置报错了,就不用重新的开头计算,只要从错误的那个点前一个依赖开始计算
注:Action算子的执行会清空血缘关系