Spark中的groupByKey 、aggregateByKey、reduceByKey 的区别

1.reduceByKey vs aggregateByKey

    假设你有一系列元组,以用户ID为key,以用户在某一时间点采访的站为value:

val userAccesses = sc.parallelize(Array("u1", "site1"), ("u2", "site1"), ("u1", "site1"), ("u2", "site3"), ("u2", "site4")))

    我们要对这个列表进行处理,获得某个用户访问过且去重后的所有站点。因groupByKey运算量较大,可选方案有reduceByKey,aggregateByKey。

    reduceByKey代码如下:

val mapedUserAccess = userAccesses.map(userSite => (userSite._1, Set(userSite._2)))
val distinctSite = mapedUserAccess.reduceByKey(_++_)

    但上述代码的问题是,RDD的每个值都将创建一个Set,如果处理一个巨大的RDD,这些对象将大量吞噬内存,并且对垃圾回收造成压力。

    如果使用aggregateByKey:

val zeroValue = collecyion.mutable.set[String]()
val aggregated = userAccesses.aggregateByKey(zeroValue)((set,v) => set += v, (setOne, setTwo) => setOne ++= setTwo)

    为避免reduceByKey内存问题,可用aggregateByKey。

    aggregateByKey函数的使用,需为它提供以下三个参数:

    1.零值(zero):即聚合的初始值

    2.函数f:(U, V)

    把值V合并到数据结构U, 该函数在分区内合并值时使用

    3.函数 g:(U, V)

    合并两个数据结构U,在分区间合并值时调用此函数。


2.原理差别

    (1)groupByKey()是对RDD中的所有数据做shuffle,根据不同的Key映射到不同的partition中再进行aggregate。

   (2)aggregateByKey()是先对每个partition中的数据根据不同的Key进行aggregate,然后将结果进行shuffle,完成各个partition之间的aggregate。因此,和groupByKey()相比,运算量小了很多。

      (3)  distinct()也是对RDD中的所有数据做shuffle进行aggregate后再去重。

    (4)reduceByKey()也是先在单台机器中计算,再将结果进行shuffle,减小运算量

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值