分组聚合类RDD总结

本文介绍了Spark中的reduceByKey、groupByKey和aggregateByKey等函数,强调了reduceByKey在预聚合和性能上的优势,并讨论了foldByKey的简化形式。还通过示例展示了如何在Scala中使用这些函数进行数据处理。
摘要由CSDN通过智能技术生成

reduceByKey

dataRDD1.reduceByKey(_+_)

可以将数据按照相同的 Key 对 Value 进行聚合

【小结】:

reduceByKey是对相同元素进行两两聚合,函数体中_+_表示相同类型key的value1+value2

groupByKey

groupByKey将相同的Key放在同一个组中,形成元组

元组第一个值为key

第二个值为,相同key的value的集合

【总结】:reduceByKey 和 groupByKey 的区别

从 shuffle 的角度:reduceByKey 和 groupByKey 都存在 shuffle 的操作,但是 reduceByKey可以在 shuffle 前对分区内相同 key 的数据进行预聚合(combine)功能,这样会减少落盘的数据量,而 groupByKey 只是进行分组,不存在数据量减少的问题,reduceByKey 性能比较

高。

从功能的角度:reduceByKey 其实包含分组和聚合的功能。GroupByKey 只能分组,不能聚合,所以在分组聚合的场合下,推荐使用 reduceByKey,如果仅仅是分组而不需要聚合。那么还是只能使用 groupByKey

aggregateByKey

包含两个参数 aggregateByKey()()

* 第一个参数是初始比较值,第一个参与两两计算的

* 第二个值是两个函数,第一个 是分区内计算函数,第二个是分区间计算函数

foldByKey

当aggregateByKey分区内逻辑和分区间逻辑相同时,可以简化为foldByKey(0)(+)

combineByKey常用

data.flatMap(_.split(" "))
  .map((_, 1))
  .combineByKey(
    v=>v,//对于第一个数据的处理,就是不处理,这里的v就是(hello,1)中的值:1
    (x:Int,v)=>x+v,//分区内的处理操作,第一个处理后的数据和后面数据的处理方式1+1+1
    (x:Int,y:Int)=>x+y//分区间的处理,第一个分区结果:3,第二个分区的结果:2,那就是3+2
  )
  .sortBy(_._2)
  .collect().foreach(println)

 aggregate


import org.apache.log4j.{Level, Logger}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

import scala.collection.mutable
object aggregateTest {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("Wc")
    val sc = new SparkContext(conf)
    val word = sc.makeRDD(
      List("Hive", "Hive", "Spark", "Scala")
    )
    //初始值传一个可变map
    word.aggregate(mutable.Map[String, Int]())(
      //初始值 和 第一个数据做计算
      (map3, s) => {
        // 给map3添加kv数据   value是通过getOrElse(s, 0) + 1得到
        map3(s) = map3.getOrElse(s, 0) + 1
        //getOrElse的意思是:如果get的S 拿到value了,证明map中有这个key,就在value+1
        //如果没有拿到,就给value赋值0 ,然后再给value +1
        map3
      },
      //分区间 对不同分区的map集合做操作, map1是集合,map2 是集合
      (map1, map2) => {
        //用foldLeft操作两个集合
        map1.foldLeft(map2)(
          //innerMap是一个map2中的每一个数据,kv是一个map1中的每一个数据
          (innerMap, kv) => {
            //给innerMap添加kv数据   value是通过getOrElse(s, 0) + 1得到
            innerMap(kv._1) = innerMap.getOrElse(kv._1, 0) + kv._2
            innerMap
          }
        )
      }).foreach(println)
  }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值