spark任务stage的分解

968 阅读2分钟
  • spark任务中stage的划分

首先按照rdd之间的依赖方式形成DAG,然后提交给DAGScheduler,DAGScheduler根据rdd之间的依赖关系(遇到宽依赖)将任务划分成多个stage。

  • spark任务stage计算方式

spark是基于内存的计算,采用pipeline的计算方式,相当于执行一个高阶函数f3(f2(f1(textFile))) !+!+!=3,也就是逻辑计算完成再落地; map-reduce 则是采用计算完成落盘,然后再计算再落到磁盘或者内存,最后输出到计算节点上,按照reduce的hash分区进行落地。相当于1 + 1 = 2, 2 + 1 = 3

  • 提高stage的并行度

stage的task并行度由最后一个rdd的分区数来决定。一般来说,一个partition对应一个task(可以解释task与partition的关系),但是最后reduce的时候可以手动改变reduce的个数,也就是分区数量来修改并行度。例如reduceByKey(XXX,3),GroupByKey(4),union由的分区数由前面的相加。

  • shuffle & stage

shuffle是spark任务中划分stage的依据,也就是说shuffle通常代表者存在rdd的宽依赖变换。在宽依赖过程中存在两个步骤,shuffle write & shuffle fetch, 类似hadoop的map和reduce两个阶段,shuffle write将ShuffleMapTask 任务产生的中间结果缓存到内存中,shuffle fetch 获得ShuffleMapTask 缓存的中间结果进行 ShuffleReduceTask 计算,这个过程容易造成OutOfMemory.

运行到每个 stage 的边界时,数据在父 stage 中按照 Task 写到磁盘上,而在子 stage 中通过网络按照 Task 去读取数据。这些操作会导致很重的网络以及磁盘的I/O,所以 stage 的边界是非常占资源的,在编写 Spark 程序的时候需要尽量避免的 。父 stage 中 partition 个数与子 stage 的 partition 个数可能不同,所以那些产生 stage 边界的 Transformation 常常需要接受一个 numPartition 的参数来觉得子 stage 中的数据将被切分为多少个 partition7。 PS:shuffle 操作的时候可以用 combiner 压缩数据,减少 IO 的消耗