Spark中groupByKey和reduceByKey的区别

重点比较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类的算子,可以直接看到返回结果)

你可能感兴趣的:(Scala,Spark)