spark-算子-分区算子partitionBy、coalesce、repartition

一、partitionBy

在这里插入图片描述

val inputRDD = sc.parallelize(Array[(Int,Char)] ((1, 'a'),(2,'b'),(3,'C') (4,'d'),(2,'e'),(3,'f'),(2,'g'),(1, 'h')),3)

val resultRDD = inputRDD.partitionBy(new HashPartitioner (2))//使用HashPartitioner重新分区
val resultRDD = inputRDD.partitionBy(new RangePartitioner(2,inputRDD))//使用RangePartitioner重新分区

同repartition区别,partitionBy是根据partitioner,而repartition是随机策略,不能指定partitioner

二、coalesce

用来改变分区数,根据随机生成的key,使用随机策略均匀的分布数据,只能传入分区数,不能指定partitioner

val sc = new SparkContext()
val inputRDD = sc.parallelize(Array[(Int, Char)]((3, 'c'), (3, 'f'), (1, 'a'), (4, 'd'), (1, 'h'), (2, 'b'), (5, 'e'), (2, 'g')), 5)
var coalesceRDD = inputRDD.coalesce(2) //图3.19中的第1个图
coalesceRDD = inputRDD.coalesce(6) //图3.19中的第2个图
coalesceRDD = inputRDD.coalesce(2, true) // 图3.19中的第3个图
coalesceRDD = inputRDD.coalesce(6, true) //图3.19中的第4个图
  1. 减少分区个数
    在这里插入图片描述
    如图319中的第1个图所示,rdd1的分区个数为5,当使用coalesce(2)减少为两个分区时,spark会将相邻的分区直接合并在一起,得到rdd2,形成的数据依赖关系是多对一的NarrowDependency.这种方法的缺点是,当rdd1中不同分区中的数据量差别较大时,直接合并容易造成数据倾斜(rdd2中某些分区数据量过多或过少)
  2. 增加分区个数
    在这里插入图片描述
    如图3.19中的第2个图所示,当使用coalesce(6)将rdd1的分区个数增加为6时,会发现生成的rdd2的分区个数并没有增加,还是5。这是因为coalesce()默认使用NarrowDependency,不能将一个分区拆分为多份。
  3. 使用Shuffle来减少分区个数:
    在这里插入图片描述
    如图3.19中的第3个图所示,为了解决数据倾斜的问题,我们可以使用coalesce(2, Shuffle = true)来减少RDD的分区个数。使用Shuffle = true后,Spark 随机将数据打乱,从而使得生成的RDD中每个分区中的数据比较均衡。具体采用的方法是为rdd1中的每个record添加一个特殊的Key,如第3个图中的MapPartitionsRDD,Key是 Int类型,并从[0, numPartitions)中随机生成,如<3,f >=><2,(3,f)>中,2是随机生成的Key,接下来的record的Key递增1,如<1,a> =><3,(1,a)>。这样,Spark可以根据Key的 Hash值将rdd1中的数据分发到rdd2的不同的分区中,然后去掉Key即可(见最后的 MapPartitionsRDD)。
  4. 使用Shuffle来增加分区个数:
    在这里插入图片描述
    如图3.19 中的第4个图所示,通过使用ShuffeDepedency,可以对分区进行拆分和充足,解决分区个数不能增加的问题。

三、repartition = coalesce(numPartitions,true)

repartition(partitionNums): Reshuffle the data in the RDD randomly to create either more or fewer partitions and balance it across them. This always shuffles all data over the network.
中文:通过创建更多或更少的分区将数据随机的打散,让数据在不同分区之间相对均匀。这个操作经常是通过网络进行数打散。
从设计的角度上来说,repartition 是用来让数据更均匀分布的

coalesce和repartition 用法

语义上的区别:repartition = coalesce(numPartitions,true)

coalesce

coalesce算子默认只能减少分区数量,如果设置为false且参数大于调用RDD的分区数,那调用RDD的分区数不会变化。

coalesce的作用常常是减少分区数,已达到输出时合并小文件的效果。减少分区数有2种情况:

  1. 直接用默认的coalesce(parNum,false),此时只有一个stage,且stage的并行度设置为coalesce的parNum,可能会对性能有影响
    在一个stage中,coalesce中设定的分区数是优先级最高的
  2. coalesce(parNum,true),此时会有2个stage,stage0仍然使用原来的并行度,然后合并分区,减少并行度。适合大数据量的过滤后小数据量的操作。
    比如有个rdd原来有200个分区,经过filter操作后,数据大幅减少,200个分区过多了,此时就可以使用coalesce(parNum,true)

repartition

repartition 返回一定一个parNum个分区的RDD,一定会shuffle,一般用这个就是为了增加分区数,提高并行度!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值