Spark-Core之源码级算子详解(二)

1.keys算子理解:
只能针对对偶元组使用,keys这个方法是定义在PariPDDfunction中,只有Rdd中装的是对偶元组才能将rdd转换为PariRDDFunction(隐式转换)
一般我们经常使用的reduceBykey或者是groupBykey  这种带有Bykey操作的算子都是先将RDD(对偶元组)通过隐式转换为PariRDDFunction 才能调用算子
keys算子底层 调用的是map方法,是对rdd中的每一个分区调用map方法
2.values算子理解:
只能针对对偶元组使用,values这个方法是定义在PariPDDfunction中,只有Rdd中装的是对偶元组才能将rdd转换为PariRDDFunction(隐式转换),相当于对rdd包了一层 
一般我们经常使用的reduceBykey或者是groupBykey  这种带有Bykey操作的算子都是先将RDD(对偶元组)通过隐式转换为PariRDDFunction 才能调用算子
values算子底层 调用的是map方法,是对rdd中的每一个分区调用map方法
3.mapValues算子
是对rdd中的values进行map操作,不用管key,将values应用传入的函数处理后 ,在于key放到对偶元组中(相当于把key拿出来原封不动,然后将values处理好后将key和处理之后的value放到对偶元组中)
底层是new了一个MapParititionsRDD,然后对迭代器调用了map方法,然后k不做改变,对value应用传入的函数
//mapValues的底层实现
val count: MapPartitionsRDD[(String, Int), (String, Iterable[Int])] = new MapPartitionsRDD[(String, Int), (String, Iterable[Int])](gb, (_, _, it) => it.map { case (k, v) => (k, v.sum) })
4. flatMapValues算子
功能,将对偶元组中的values进行传入的函数操作,然后将values压平,在将压平后的每一个元素和key组合成新的对偶元组,可能会将一行数据变为多行
底层实现,是new了一个MapParititionsRDD,然后将每一个迭代器调用flatMap操作,组成新的对偶元组,flatMap要求返回值必须是数组集合或者是迭代器,才能将这些集合压平

val flv: MapPartitionsRDD[(String, Int), (String, String)] = new MapPartitionsRDD[(String, Int), (String, String)](rdd, (_, _, it) => it.flatMap {
  case (k, v) => {
    val tuples: Array[(String, Int)] = v.split(",").map(e => {
      val tuple: (String, Int) = (k, e.toInt)
      tuple
    })
    tuples
  }
})    


5. union算子
功能是将多个rdd合并到一起(生成一个新的rdd用来,描述之前的两个rdd,新的rdd的分区数量是之前两个rdd的分区数量之和,并且分区编号改变),但是不会去重里面的数据,而且不会有shuffle ,不会用到分区器,
union不需要数据移动,还是在原来的机器
每一个stage中task的数量是由分区中最后一个rdd中分区的数量决定的
union算子的底层实现:先将第一个 rdd 放入seq集合中,然后通过seq(rdd1)++rdd2,生成一个新的集合,里面装有两个rdd,union底层又new 了一个UnionRDD,
rdd3的分区数量是由new UnionRDD,然后调用UnionRDD中的方法getPartitions 具体的逻辑是(parRDDs.map(_.partitions.length).sum)  parRDDs值得就是装有两个rdd的集合,就是遍历集合然后求出每个rdd的分区数量,然后再求和
6. foldByKey算子
作用效果和reduceByKey一样,都是先局部聚合然后在全局聚合,可以指定一个初始值
foldByKey是一个柯里化方法,初始值会被应用几次:每一个分区每个key应用一次初始值(注意:局部聚合应用初始值(底层combineByKey中传入的第一个函数(init:Int,v:int=>init+v),只有key第一次出现的时候被调用一次),全局聚合不会应用初始值)
底层实现:和reduceByKey类似:底层也是调用了combineByKey但是和reduceByKey不同的是需要传入的三个函数中,第一个函数是将每一个key第一次出现的value和初始值进行聚合,combineByKey底层调用的是shuffleRDD
7.AggregateByKey算子
也可以实现wordCount的功能,也可以传入初始值,reduceByKey相比更加灵活,可以传局部聚合的函数,也可以传全局聚合的函数,这两个函数可以是不同逻辑的函数,所以更加灵活(需求:是局部聚合求相同key的最大值,全局聚合求sum)补充:求相同key的最大值,可以使用函数:Math.max(_,_)
底层调用也是combineByKey,如果以后有很复杂得逻辑,我们可以使用combineByKey更加灵活
8. cogroup算子
联合分组,对多个rdd分组,每一个rdd中key相同的value会放在同一个迭代器中,cogroup可以对两个即以上的rdd(一个rdd最多可以传入3个rdd,不能大于4个)
与groupByKey的区别是:groupByKey只是对一个RDD按照key进行分区,Cogroup可以对多个RDD进行分组,key相同的数据一定会进入同一个分区的同一个组内,value是进入到多个compactBuffer中
生成的结果为: Array[(String, (Iterable[Int], Iterable[Int]))] = Array((jim,(CompactBuffer(2, 6),CompactBuffer(2, 6))), (zxx,(CompactBuffer(),CompactBuffer(6))), (tom,(CompactBuffer(3, 1),CompactBuffer(1, 3)))),
从结果中可以看出:只有当第一个compactBuffer中有数据和第二个compactBuffer中有数据,才能进行join操作

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值