Spark11: 算子优化

一、map vs mapPartitions

  • map 操作:对 RDD 中的每个元素进行操作,一次处理一条数据
  • mapPartitions 操作:对 RDD 中每个 partition 进行操作,一次处理一个分区的数据

1. 优缺点及使用场景

        1)map 操作: 执行 1 次 map算子只处理 1 个元素,如果 partition 中的元素较多,假设当前已经处理了1000 个元素,在内存不足的情况下,Spark 可以通过GC等方法回收内存(比如将已处理掉的 1000个元素从内存中回收)。因此, map 操作通常不会导致OOM异常;

        2)mapPartitions 操作: 执行 1 次map算子需要接收该 partition 中的所有元素,因此一旦元素很多而内存不足,就容易导致OOM的异常,也不是说一定就会产生OOM异常,只是和map算子对比的话,相对来说容易产生OOM异常

        3)不过一般情况下,mapPartitions 的性能更高;初始化操作、数据库链接等操作适合使用 mapPartitions操作,这是因为:假设需要将RDD中的每个元素写入数据库中,这时候就应该把创建数据库链接的操作放置在mapPartitions 中,创建数据库链接这个操作本身就是个比较耗时的,如果该操作放在 map 中执行,将会频繁执行,比较耗时且影响数据库的稳定性。

二、foreach vs foreachPartition

  • foreach:一次处理一条数据
  • foreachPartition:一次处理一个分区的数据

1. 二者区别

        foreachPartition的特性和mapPartitions 的特性是一样的,唯一的区别就是mapPartitions 是 transformation 操作(不会立即执行),foreachPartition是 action 操作(会立即执行)

三、repartition的使用

1. 对RDD进行重分区,repartition主要有两个应用场景:

        1)可以调整RDD的并行度
        针对个别RDD,如果感觉分区数量不合适,想要调整,可以通过repartition进行调整,分区调整了之后,对应的并行度也就可以调整了
        2)可以解决RDD中数据倾斜的问题
        如果RDD中不同分区之间的数据出现了数据倾斜,可以通过repartition实现数据重新分发,可以均匀分发到不同分区中

四、reduceByKey vs groupByKey

1. 二者区别

        在实现分组聚合功能时这两个算子有什么区别?看这两行代码

val counts = wordCountRDD.reduceByKey(_ + _)
val counts = wordCountRDD.groupByKey().map(wc => (wc._1, wc._2.sum))

        这两行代码的最终效果是一样的,都是对wordCountRDD中每个单词出现的次数进行聚合统计,那这两种方式在原理层面有什么区别吗?首先这两个算子在执行的时候都会产生shuffle。但是:
        1:当采用reduceByKey时,数据在进行shuffle之前会先进行局部聚合
        2:当使用groupByKey时,数据在shuffle之前不会进行局部聚合,会原样进行shuffle
        这样的话reduceByKey就减少了shuffle的数据传送,所以效率会高一些。下面来看这个图,加深一下理解

        从图中可以看出来reduceByKey在shuffle之前会先对数据进行局部聚合,而groupByKey不会,所以在实现分组聚合的需求中,reduceByKey性能略胜一筹。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值