Spark中coalesce与repartition的区别?

Spark

Spark中coalesce与repartition的区别?

[TOC]

相同

  • 二者都是对 RDD 的分区进行重新划分

区别

  • shuffle操作
    • repartition(numPartitions:Int):RDD[T]
    • repartition 只是 coalesce 接口中 shuffle 为 ture 的实现,故产生 shuffle 操作
    • **coalesce(numPartitions:Int,shuffle:Boolean=false):RDD[T] **
    • coalesce 中的 shuffle 默认为 false ,故不会产生 shuffle 操作
  • 分区数:少对多
    • 一般情况下少分区转换为多分区,利用 HashPartitioner 函数将数据重新分区,这时候的父子RDD关系为一对多,为宽依赖,所以会产生shuffle 操作,需只能用 repartition 算子
    • coalesce 算子实现不了
  • 分区数:多对少【多少差别不大】
    • 假设原分区数为 1000,现要求分区数为10。那么就阔以将1000个分区中的若干个分区合并成一个新的分区,最终合并成10各分区。这个时候的父子RDD关系为多对一,为窄依赖,不会产生shuffle 操作,只能使用 coalesce 算子
    • repartition 算子实现不了
  • 分区数:多对少【多少差别巨大】
    • 一般这个时候需要看 executor 数和要生成的 partition 的关系
    • executor <= partition
      • coalesce 的效率会高
    • executor => partition
      • 反之的话 coalesce 会导致(executor数 - partition数)个executor 空跑,从而降低效率

实例

​ T表有10G数据 有100个partition 资源也为–executor-memory 2g –executor-cores 2 –num-executors 5。我们想要结果文件只有一个

coalesce

​ sql(select * from T).coalesce(1) 5个executor 有4个在空跑,只有1个在真正读取数据执行,这时候效率是极低的。所以coalesce要慎用,而且它还用产出oom问题,这个我们以后再说。

repartition

​ sql(select * from T).repartition(1) 这样效率就会高很多,并行5个executor在跑(10个task),然后shuffle到同一节点,最后写到一个文件中 那么如果我不想产生一个文件了,我想产生10个文件会怎样,是不是coalesce 又变得比 repartition高效了呢。(因为coalesce无shuffle,相当于每个executor的 task认领 10个 partition) 那么如果我又不想产生10个文件呢?其实一旦要产生的文件数大于executor x vcore数,coalesce效率就更高(一般是这样,不绝对)。

总结

​ 我们常认为coalesce不产生shuffle会比repartition 产生shuffle效率高,而实际情况往往要根据具体问题具体分析,coalesce效率不一定高,有时还有大坑,大家要慎用。 coalesce 与 repartition 他们两个都是RDD的分区进行重新划分,repartition只是coalesce接口中shuffle为true的实现(假设源RDD有N个分区,需要重新划分成M个分区)

​ 1)如果N<M。一般情况下N个分区有数据分布不均匀的状况,利用HashPartitioner函数将数据重新分区为M个,这时需要将shuffle设置为true(repartition实现,coalesce也实现不了)。

​ 2)如果N>M并且N和M相差不多,(假如N是1000,M是100)那么就可以将N个分区中的若干个分区合并成一个新的分区,最终合并为M个分区,这时可以将shuff设置为false(coalesce实现),如果M>N时,coalesce是无效的,不进行shuffle过程,父RDD和子RDD之间是窄依赖关系,无法使文件数(partiton)变多。 总之如果shuffle为false时,如果传入的参数大于现有的分区数目,RDD的分区数不变,也就是说不经过shuffle,是无法将RDD的分区数变多的

​ 3)如果N>M并且两者相差悬殊,这时你要看executor数与要生成的partition关系,如果executor数 <= 要生成partition数,coalesce效率高,反之如果用coalesce会导致(executor数-要生成partiton数)个excutor空跑从而降低效率。如果在M为1的时候,为了使coalesce之前的操作有更好的并行度,可以将shuffle设置为true。