Spark为什么只有在调用action时才会触发任务执行呢(附算子优化和使用示例)?

Spark的transformation算子不会立即执行,而是在调用action时触发任务。这是因为transformation是懒加载的,可以减少不必要的计算和资源消耗。例如,map、flatMap和filter等transformation会在action如collect、count时才执行。reduceByKey相比于groupByKey在性能上有优势,因为它先在map端局部聚合,再reduce端全局聚合,类似于MapReduce的combiner。了解这些原理和优化,能更好地运用Spark进行大数据处理。
摘要由CSDN通过智能技术生成

Spark算子主要划分为两类:transformation和action,并且只有action算子触发的时候才会真正执行任务。还记得之前的文章《Spark RDD详解》中提到,Spark RDD的缓存和checkpoint是懒加载操作,只有action触发的时候才会真正执行,其实不仅是Spark RDD,在Spark其他组件如SparkStreaming中也是如此,这是Spark的一个特性之一。像我们常用的算子map、flatMap、filter都是transformation算子,而collect、count、saveAsTextFile、countByKey、foreach则为action算子。
在这里插入图片描述
但初学Spark的人往往都会有这样的疑惑,为什么Spark任务只有在调用action算子的时候,才会真正执行呢?咱们来假设一种情况:假如Spark中transformation直接触发Spark任务!那么会产生什么结果呢?

  1. 导致map执行完了要立即输出,数据也必然要落地(内存和磁盘)
  2. map任务的生成、调度、执行,以及彼此之间的rpc通信等等,当牵扯到大量任务、大数据量时,会很影响性能

看到这两点是不是很容易联想到MapReduce的计算模型,MapReduce因为中间结果需要落地,导致性能相对Spark较低下,这也是MapReduce广为诟病的原因之一。所以Spark采用只有调用action算子时才会真正执行任务,这是相对于MapReduce的优化点之一。

但是每个Spark RDD中连续调用多个map类算子,Spark任务是对数据在一次循环遍历中完成还是每个map算子都进行一次循环遍历呢?
答案很确定:不需要对每个map算子都进行循环遍历。Spark会将多个map算子pipeline起来应用到RDD分区的每个数据元素上(后续将要介绍的SparkSQL中的Dataset/DataFrame也是如此)

下面说几个算子的优化,这也是面试中经常问的问题:

在我们实际的业务场景中经常会使用到根据key进行分组聚合的操作,当然熟悉Spark算子使用的都知道像reduceByKey、groupByKey、aggregateByKey、combineByKey大多都能满足需求。但是笔者在这里还是要重点说一下,因为很多人想到分组聚合往往第一个想到的算子就是groupByKey,但是groupByKey相对其他算子性能低并且处理不好的情况下,容易发生数据倾斜。所以我们能用其他算子比如reduceByKey替代groupByKey实现满足我们业务需求的,就一律不用groupByKey。当然reduceByKey在某些场景下性能会比aggregateByKey低,具体算子的替换要结合实际业务需求场景来定。

这里主要说明一下reduceByKey和groupByKey的对比,以及几个算子替代的场景示例:
1.首先这几个“ByKey”的算子会触发shullfe,这里强调一点,对于分布式任务,如果存在聚合操作的话往往都是要进行shuffle的
2.相对于reduceByKey,groupByKey没有预先聚合,而是直接将相同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值