Spark-之聚合算子的关系与区别
- reduceByKey
- aggregateByKey
- foldByKey
- combineByKey
四种聚合方式都是在shuffle之前在分区内作预先聚合的操作,相对比groupByKey + map的方式,这些性能更加好,因为从map -> 磁盘 -> reduce这个过程中的mapstage的io减少了。
这些函数的过程分为:
1、分区内聚合map端聚合
2、分区间的shuffle聚合
下面通过4种不同的算子实现 wordcount操作!!
# 定义RDD
val rdd: RDD[(String, Int)] = sc.makeRDD(List(
("a", 1), ("a", 2), ("b", 2), ("a", 3)
), 2)
// TODO 1 reduceByKey(), 不会将相同key的value类型作转换,返回值的value类型与
val rdd1: RDD[(String, Int)] = rdd.reduceByKey(_ + _)
println(rdd1.collect().mkString(","))
// TODO 2 aggregateByKey(),可以将相同key的value类型作转换,zero参数的类型与返回值的类型是一致的
val rdd1: RDD[(String, Int)] = rdd.aggregateByKey(0)(
_ + _, //分区内聚合
_ + _ //分区间聚合
)
// TODO 3 foldByKey(),属于aggregateByKey的特殊版本,分区内聚合与分区间聚合的方式一样
val rdd1: RDD[(String, Int)] = rdd.foldByKey(0)(_ + _)
// TODO 4 combineByKey(), 相当于将aggregateByKey给初始运算参考值的操作,通过将第一个元素转换成对应的类型,然后参与后续运算
val rdd3: RDD[(String, Int)] = rdd.combineByKey(
x => x, //运算前的类型转换
(x: Int, v) => x + v, //分区内聚合
(x: Int, y: Int) => x + y //分区间聚合
)
1 相同key的平均数(案例)
使用aggregateByKey和combineByKey配合map实现比较简单,主要过程如下:
- 确定返回RDD元素类型为:(count,sum),平均数为 sum/count
- 分区内操作,通过 初始值与当前value做merge
- 分区间操作,通过将相同key的不同的(count,sum),(count,sum)进行merge
具体代码如下。
- aggregateByKey
// TODO 初始值的类型与RDD返回值的value的类型是一样的
val value: RDD[(String, (Int, Int))] = rdd.aggregateByKey((0, 0)) // 给定初始值,这个也是返回值的value的类型
(
(tuple, v) => (tuple._1 + 1, tuple._2 + v), //分区内作聚合(count+1,sum+v)
(tuple1, tuple2) => (tuple1._1 + tuple2._1, tuple1._2 + tuple2._2) //分区间作聚合(count1+count2,sum1+sum2)
)
// 计算相同key的平均值
val avgRDD: RDD[(String, Int)] = value.map {
case (key, tuple) => (key, tuple._2 / tuple._1)
- combineByKey
// TODO 初始值的类型与RDD返回值的value的类型是一样的
val rdd1: RDD[(String, (Int, Int))] = rdd.combineByKey(
intVal => (1, intVal), //初始值进行转换,然后方便两两进行运算val => (count=1,sum=val)
(t: (Int, Int), v) => (t._1 + 1, t._2 + v), //分区内作聚合(count+1,sum+v)
(t1: (Int, Int), t2: (Int, Int)) => (t1._1 + t2._1, t1._2 + t2._2) //分区间作聚合(count1+count2,sum1+sum2)
)
val avgRDD: RDD[(String, Int)] = rdd1.map {
case (key, t) => (key, t._2 / t._1)
}
1722

被折叠的 条评论
为什么被折叠?



