spark重分区算子repartition和coalesce解析

    在spark中,有时候我们觉得task并行度太小,就想着提高其并行度。
    首先,先说一下有多少种增加分区提高并行度的方法:
1,textFile(path, numPartion=partitionNum)
2,增加hdfs上的block数
3,reduceByKey groupByKey shuffle算子可以指定返回的RDD的分区数,如reduceByKey(+, 10)
4,重分区 coalesce repartition
5,自定义分区器 partionBy

    总体上来说,就以上五类方法。下面我们就来做进一步的讲解。
     需要强调的是,所谓并行度,我们并不是说增加分区就是增加并行度,而是通过增加分区,运行更多的task,这样来增加并行度。
     这里有一个重要的概念就是每一个stage task的个数与这个stage中的最后一个RDD的分区相关

spark重分区算子repartition和coalesce解析_第1张图片
    如图中,rdd1、rdd2和rdd3三个rdd属于同一个stage,由三个task执行。
    可能这里就有读者会问道,为什么是最后一个rdd决定,而不是前面的rdd决定的呢? 下面将展示一个特殊案例:
spark重分区算子repartition和coalesce解析_第2张图片
    图中可以看到,rdd0和rdd1通过union得到rdd3,一种产生4个task,而rdd1和rdd0都只有2个分区。那么这就很好的解释了为什么是最后一个rdd的分区决定task的数量了吧。

    另外的,鉴于前三种增加rdd分区的方式相对好理解。这里重点解释一下repartition和coalesce两个增加分区的算子。
    对于repartion:
用法是rdd.repartition(partitonNum)spark重分区算子repartition和coalesce解析_第3张图片
从图中可以直接了解到,repartition有一个shuffle的过程。即将每一个partition中的数据,循环遍历,分到对应的分区中。同理,对应到减小分区也是这样操作。
    对于coalesce:
用法 coalese(partitionNum, True/False)
spark重分区算子repartition和coalesce解析_第4张图片
其中,partitionNum表示新分区个数,True和False表示是否shuffle。
图中的结构,表示将3分区重新分区为2分区。可以用rdd1.coalesce(2, False)来分区。但是这里,如果我们想要将rdd2变为4分区,则语句为rdd1.coalesce(4, True),需要注意的是,分区增加就必须将是否shuffle设置为True了。

总结:
如果想要增加rdd的分区,必须使用带有shuffle的重分区方式,repartition/coalesce(num, true)

如果想要减少rdd的分区,可以不使用带有shuffle的重分区方式,coalesce(num, false)

你可能感兴趣的:(大数据)