Spark学习过程中遇到RDD的aggregate(zeroValue :U)(seqOp:(U,Int)=> U),combOp :(U,U)=> U)方法,如果我们使用这个方法来计算RDD的平均值的话(这里我用的scala):
val arr = Array(1,2,3,4,5,,6)
val rdd = sc.parallelize(arr,1)
val result = rdd.aggregate(0,0)((x,y)=>(x._1+y,x._2+1),(m,n) => (m._1+n._1,m._2+n._2))
val avgNum = result._1/result._2.toDouble
这里我们RDD分区为1个分区的情况,(0,0)为初始值,代码中(x,y)=>(x._1+y,x._2+1)以下我们称为:函数1;(m,,n)=>(m._1+n._1,m._2+n._2)称为:函数2.
在函数1中,x为初始值,y为RDD中的值,函数2中m为初始值,n为函数1返回的值,所以代码中函数1的运行过程为:
(x._1+y) (x._2+1)
(0+1) (0+1)
(1+2) (1+1)
(3+3) (2+1)
(6+4) (3+1)
(10+5) (4+1)
(15+6) (5+1)
函数2的运行过程为:
(m._1+n._1) (m._2+n._2)
(0+21) (0+6)
上面是我们RDD分区为1的情况,如果RDD分区为2的话,也就是 val rdd = sc.parallellize(arr,2),RDD中数据分为两个partition,分别为part1:(1,2,3) part2:(4,5,6)
那么函数1的运行过程为:
part 1:(x._1+y) (x._2+1) part2 : (x._1+y) (x._2 + 1)
(0+1) (0+1) (0+4) (0+1)
(1+2) (1+1) (4+5) (1+1)
(3+3) (2+1) (9+6) (2+1)
函数1运行结果为:part1 :(6,3) part2:(15,3)
函数2的运行是将RDD的两个partition聚合的过程为:(0+6,0+3)
(6+15,3+3)
当然RDD分区多的时候依次类推,运行原理大概就是这样