在Spark中,依赖关系是指RDD之间的依赖关系。根据依赖关系的不同,可以将其分为宽依赖和窄依赖。
窄依赖:当父RDD的每个分区只被子RDD的一个分区所使用时,就称为窄依赖。这种依赖关系可以通过单个stage完成计算,也就是说,一个stage中的多个任务可以并行执行。例如,map、filter等操作都是窄依赖。
宽依赖:当父RDD的一个分区被多个子RDD的分区所使用时,就称为宽依赖。这种依赖关系需要进行shuffle操作,即数据的重新分配和排序,因此会产生网络传输和磁盘I/O等开销。例如,reduceByKey、groupByKey等操作都是宽依赖。
举例说明:
假设有两个RDD,RDD1和RDD2,其中RDD2依赖于RDD1。如果RDD2的每个分区只依赖于RDD1的一个分区,则称为窄依赖;如果RDD2的每个分区依赖于RDD1的多个分区,则称为宽依赖。
例如,下面的代码展示了一个窄依赖的例子:
```
val rdd1 = sc.parallelize(Seq(1, 2, 3, 4, 5))
val rdd2 = rdd1.map(_ * 2)
```
在这个例子中,rdd2依赖于rdd1,但是rdd2的每个分区只依赖于rdd1的一个分区,因此这是一个窄依赖。
再举一个宽依赖的例子:
```
val rdd1 = sc.parallelize(Seq(("a", 1), ("b", 2), ("c", 3)))
val rdd2 = rdd1