Spark中groupByKey和reduceByKey的区别

8 篇文章 0 订阅

重点比较reduceByKey和groupByKey:

相同点:
1,都作用于 RDD[K,V]
2,都是根据key来分组聚合
3, 默认,分区的数量都是不变的,但是都可以通过参数来指定分区数量

不同点:
1, groupByKey默认没有聚合函数,得到的返回值类型是RDD[ k,Iterable[V]]
2, reduceByKey 必须传聚合函数 得到的返回值类型 RDD[(K,聚合后的V)]
3, groupByKey().map() = reduceByKey

最重要的区别:
reduceByKey 会进行分区内聚合,然后再进行网络传输
groupByKey 不会进行局部聚合

结论:
如果这两个算子,都可以使用, 优先使用reduceByKey

具体代码如下:

import org.apache.spark.rdd.RDD
import org.apache.spark.{Partitioner, SparkConf, SparkContext}

/**
  * @author WangLeiKai
  *         2018/9/18  16:19
  */
object ReduceByKeyDemo {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setAppName("ReduceByClass")
    
    conf.setMaster("local[*]")//设置为本地运行
    
    //设置程序的入口
    val sc: SparkContext = new SparkContext(conf)
    
    //创建RDD
    val rdd1: RDD[Int] = sc.makeRDD(List(1,2,3,4,5))
    
    //调用groupBy方法
    val groupedRdd1: RDD[(String, Iterable[Int])] = rdd1.groupBy(t => t.toString)

    val rdd2: RDD[(String, Int)] = sc.makeRDD(List(("rb", 1000), ("baby", 990),
      ("yangmi", 980), ("bingbing", 5000), ("bingbing", 1000), ("baby", 2000)), 3)
  
    val groupByKeyRDD2: RDD[(String, Iterable[Int])] = rdd2.groupByKey(2)
    
      val groupByKeyRDD1: RDD[(String, Iterable[Int])] = rdd2.groupByKey()
    //调用groupByKey + mapValues 就相当于 reduceByKey方法
    val result: RDD[(String, Int)] = groupByKeyRDD1.mapValues(_.sum)

    val reduceByKeyRDD: RDD[(String, Int)] = rdd2.reduceByKey(_+_)
    val rdd6: RDD[(String, Int)] = rdd2.reduceByKey(_ + _)
    
    // 指定生成的rdd的分区的数量
    val rdd7: RDD[(String, Int)] = rdd2.reduceByKey(_ + _, 10)

    val rdd5: RDD[(String, List[Int])] = sc.makeRDD(List(("a", List(1, 3)), ("b", List(2, 4))))
    rdd5.reduceByKey(_ ++ _)

    sc.stop()

  }
}

注意:如果想查看执行结果的话,可以调用foreachPartition(println)方法,然后再toString(foreachPartition(println)是RDD的Action类的算子,可以直接看到返回结果)

### 回答1: groupByKeyreduceByKey是在Spark RDD常用的两个转换操作。 groupByKey是按照键对元素进行分组,将相同键的元素放入一个迭代器。这样会导致大量的数据被发送到同一台机器上,因此不推荐使用。 reduceByKey是在每个分区对元素进行分组,然后对每组数据进行聚合操作。最后再对所有分区的结果进行聚合。因为减少了数据的移动,所以性能更优。 ### 回答2: 在SparkgroupByKey()和reduceByKey()是两个非常重要的转换操作。尽管它们都可以用来对RDD数据集的键值对进行聚合操作,但它们的实现方式和用途存在一定的区别groupByKey()是对RDD所有拥有相同键的元素进行分组,将它们组合成字典式的对应关系,并将结果以(键, 值列表)的形式返回。这个函数是非常常见的,它可以帮助我们对键值对进行分组操作,但是它可能会对内存造成严重的影响,尤其是对于大的数据集和分组非常多的情况。对于大数据集,groupByKey()可能会导致内存不足,应该尽量避免使用。 reduceByKey()的核心思想是在分布式环境下执行reduce操作。类似于groupByKey(),reduceByKey()也按键将所有元素进行分组,但是它不是用一个完整的列表将所有值存储在集群,而是将它们在每个分区进行汇总并将结果返回到主程序,然后使用reduce操作将这些值合并为一个汇总值。 这个汇总值仅在reduce操作完成后返回到驱动程序,所以reduceByKey()不会对内存造成过多的压力。因为reduceByKey()是在分布式环境下操作的,所以它执行非常高效。 因此,reduceByKey()是比groupByKey()更好的转换操作,因为它在分布式环境下执行,能够高效地处理大数据集,并且减少了RDD的数据移动,节省内存。 但是,有些情况下,groupByKey()还是可以使用的,例如,在数据量较小的情况下,或者需要将所有的键值对都分组的情况下。 ### 回答3: 在Apache SparkGroupByKeyReduceByKey都是对数据进行聚合的操作,但它们的实现方式有所不同。 GroupByKey按照key对RDD进行分组,然后返回具有相同key的元素的迭代器。它将相同的key下的所有元素放入一个可迭代的列表,然后返回一个元组(key, value)的RDD。例如,如果我们有一个(key, value)的RDD,其key为字符串类型,value为整数类型,想要按照key进行分组并将所有value相加,则可以使用GroupByKey操作来实现。 ReduceByKey操作也按照key对元素进行分组,但它是在分布式环境下对每个key下的元素进行归约(reduce)操作。这个归约操作可以是任何转换,例如加法、减法等。由于Spark是分布式的,ReduceByKey可以在每个节点上并行地执行reduce操作,这使得它比GroupByKey更快。同时,ReduceByKey也返回一个(key, value)的RDD,其value是每个key下归约后的结果。 总的来说,GroupByKeyReduceByKey都是将RDD的元素按照key进行分组,但ReduceByKey在执行reduce操作后返回的结果更快。如果只是对数据进行简单的分组,使用GroupByKey会更加适合,而如果需要对数据进行轻量级的归约操作,使用ReduceByKey会更加高效。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值