在Spark程序中,reduceByKey算子和groupByKey算子都是会产生shuffle过程的算子,那么它们都是怎么使用的,它们有什么区别呢?优先使用哪一个算子怎么选择呢?如果你不知道的话,下面我们一起看看吧!
一、groupByKey算子
groupByKey对每个key进行操作,但只生成一个seq,并不进行聚合。groupByKey可以指定分区器或者分区数(默认使用HashPartitioner)。
案例实现:统计单词出现次数。
object KeyValue03_groupByKey {
def main(args: Array[String]): Unit = {
//1.创建SparkConf并设置App名称
val conf: SparkConf = new SparkConf().setAppName("SparkCoreTest").setMaster("local[*]")
//2.创建SparkContext,该对象是提交Spark App的入口
val sc: SparkContext = new SparkContext(conf)
//3具体业务逻辑
//3.1 创建第一个RDD
val rdd = sc.makeRDD(List(("a",1),("b",5),("a",5),("b",2)))
//3.2 将相同key对应值聚合到一个Seq中
val group: RDD[(String, Iterable[Int])] = rdd.groupByKey()
//3.3 计算相同key对应值的相加
val res: RDD[(String, Int)] = group.map(t=>(t._1,t._2.sum))
// 3.4 触发计算,查看运行结果
res.collect()
Thread.sleep(99999)
//4.关闭连接
sc.stop()
}
}
运行结果截图:
二、reduceByKey算子
reduceByKey操作可以将RDD[K,V]中的元素按照相同的K对V进行聚合。其存在多种重载形式,还可以设置新RDD的分区数。
案例实现:统计单词出现次数。
object KeyValue02_reduceByKey {
def main(args: Array[String]): Unit ={
//1.创建SparkConf并设置App名称
val conf: SparkConf = new SparkConf().setAppName("SparkCoreTest").setMaster("local[*]")
//2.创建SparkContext,该对象是提交Spark App的入口
val sc: SparkContext = new SparkContext(conf)
//3具体业务逻辑
//3.1 创建第一个RDD
val rdd = sc.makeRDD(List(("a",1),("b",5),("a",5),("b",2)))
//3.2 计算相同key对应值的相加结果
val reduce: RDD[(String, Int)] = rdd.reduceByKey((v1,v2) => v1+v2)
//3.3 触发计算,查看运行结果
reduce.collect()
Thread.sleep(99999)
//4.关闭连接
sc.stop()
}
}
运行结果截图:
三、总结
reduceByKey:按照key进行聚合,在shuffle之前有combine(预聚合)操作,返回结果是RDD[K,V]。
groupByKey:按照key进行分组,直接进行shuffle。
开发指导:上面的运行结果截图显示,reduceByKey算子的shuffle阶段产生的数据量远少于groupByKey算子,所以在不影响业务逻辑的前提下,优先选用reduceByKey算子。
求和操作不影响业务逻辑,选择使用reduceByKey算子,求平均值影响业务逻辑,选择使用groupByKey算子。