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)
}
}