spark算子中reduceByKey和groupByKey两者的区别

spark中算子应该是重点中的重点了,今天我们来分析一下两个算子reduceByKey和groupByKey

这两个算子都属于k-v类型的算子

我们先来看看这两个算子的作用是什么?

reduceByKey是通过key对数据进行聚合

groupByKey是通过key对数据进行分组

这两个都需要对数据进行打乱重组,所以都会有shuffle

两者的区别:

  1. reduceByKey:在shuffle之前有combine(预聚合)操作,返回结果是RDD[k,v]。
  2. groupByKey:直接进行shuffle。

我们来看看reduceByKey的源码,为什么会在shuffle之前有预聚合的操作

def reduceByKey(func: (V, V) => V): RDD[(K, V)] = self.withScope {
    reduceByKey(defaultPartitioner(self), func)
  }

我们看到方法里又进行了一步操作,再进去看看

  def reduceByKey(partitioner: Partitioner, func: (V, V) => V): RDD[(K, V)] = self.withScope {
    combineByKeyWithClassTag[V]((v: V) => v, func, func, partitioner)
  }

我们看groupByKey的源码

  def groupByKey(partitioner: Partitioner): RDD[(K, Iterable[V])] = self.withScope {
    // groupByKey shouldn't use map side combine because map side combine does not
    // reduce the amount of data shuffled and requires all map side data be inserted
    // into a hash table, leading to more objects in the old gen.
    val createCombiner = (v: V) => CompactBuffer(v)
    val mergeValue = (buf: CompactBuffer[V], v: V) => buf += v
    val mergeCombiners = (c1: CompactBuffer[V], c2: CompactBuffer[V]) => c1 ++= c2
    val bufs = combineByKeyWithClassTag[CompactBuffer[V]](
      createCombiner, mergeValue, mergeCombiners, partitioner, mapSideCombine = false)
    bufs.asInstanceOf[RDD[(K, Iterable[V])]]
  }

我们可以看到两者最后调用的都是combineByKeyWithClassTag方法

而该方法参数的含义:

(1)createCombiner: 表示的是将相同key第一次出现的value的转换操作

(2)mergeValue: 分区内数据的计算规则

(3)mergeCombiners: 分区间数据的计算规则

这样我们可以知道了,reduceByKey在分区间做操作之前会对分区内数据先进行一次操作,也就是我们说的预聚合操作,而groupByKey方法就是简单的将所有的相同key的value元素进行分组聚合,数据量不会减少

所以,对于不影响业务逻辑时,非常建议使用reduceByKey方法而不是groupByKey

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值