原始的RDD通过一系列的转换就就形成了DAG,根据RDD之间的依赖关系的不同将DAG划分成不同的Stage(按宽依赖划分Stage)
窄依赖是指父类分区的数据,被子类RDD中的指定的唯一一个分区消费
宽依赖就是子类的分区的数据,要依赖多个父类RDD的分区,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据。
举个栗子:(WordCount又是你!)
textFile.flatMap(_.split(" ")).map((_,1)).reduceByKey((x,y)=>x+y).saveAsTextFile(“balabala")
flatmap map明显都是父子一对一,reduceByKey明显,一个子的kv,需要多个partition里的kv聚一块才能得到(Shuffle),所以宽依赖,划一刀,结束
PS : Spark Shuffle
涉及到shuffle 过程,前一个stage 的 ShuffleMapTask 进行 shuffle write, 把数据存储在 blockManager 上面, 并且把数据位置元信息上报到 driver 的 mapOutTrack 组件中, 下一个 stage 根据数据位置元信息, 进行 shuffle read, 拉取上个stage 的输出数据。
HashBasedShuffle(M*R个小文件!太多啦) ——> Consolidation(在同一个 core 上先后运行的两个 map task的输出, 对应同一个文件的不同的 segment上, 称为一个 FileSegment, 形成一个 ShuffleBlockFile) ——> Sort Based Shuffle(map端的任务会按照Partition id以及key对记录进行排序。同时将全部结果写到一个数据文件中,同时生成一个索引文件) ——> Tungsten-Sort Based Shuffle(使用堆外内存和新的内存管理模型,节省了内存空间和大量的gc, 提升了性能)