RDD的依赖关系
在Spark中,RDD分区的数据不支持修改,是只读的。如果想要更新RDD分区中数据,那么只能对原有RDD进行转化操作,也就是在原有RDD基础上创建一个新的RDD。
那么,在整个任务的运算过程中,RDD 的每次转换都会生成一个新的 RDD,因此 RDD 们之间会产生前后依赖的关系。
如何区分宽窄依赖
在spark中有两种依赖,即宽依赖和窄依赖。
窄依赖
父RDD的一个分区只会被子RDD的一个分区依赖
图右边是窄依赖,父RDD的每个分区的数据直接到子RDD的对应一个分区(一分区对一分区),例如1号到5号分区的数据都只进入到子RDD的一个分区,这个过程没有shuffle。Spark中Stage的划分就是通过shuffle来划分。(shuffle可理解为数据的从原分区打乱重组到新的分区)如:map,filter
宽依赖
父RDD的一个分区会被子RDD的多个分区依赖(涉及到shuffle)
图中左边是宽依赖,父RDD的4号分区数据划分到子RDD的多个分区(一分区对多分区),这就表明有shuffle过程,父分区数据经过shuffle过程的hash分区器(也可自定义分区器)划分到子RDD。例如GroupByKey,reduceByKey,join,sortByKey等操作。
设计宽窄依赖的意义
窄依赖
- 对于窄依赖而言,我们可以在 RDD 的数据分片所在的节点上,执行转换操作,让计算靠近存储,避免数据在网络上传输。而如果多个连续的转换操作构成窄依赖,那它们都可以在同一个节点,并且是数据分片所在的节点上执行。
- 窄依赖的下游 RDD 如果损坏了,只需要根据上游 RDD 重新计算,来恢复丢失的分区,由于它依赖的节点少,所以恢复的速度会很快。提高容错性。
- 进行并行计算。
宽依赖
- 对于宽依赖而言,我们需要从多个上游 RDD 获取数据。
- 下游 RDD 损坏时,也可以通过多个上游 RDD 恢复。不过恢复宽依赖的下游 RDD,消耗的网络带宽和计算资源,会比窄依赖的下游 RDD 大得多。这个时候,我们其实可以持久化下游 RDD,当出现故障时就从磁盘中恢复,来加快恢复的速度。
- 是划分Stage的依据