Spark RDD中的aggregate函数理解

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

/**
 * Created by EA on 2016/8/24.
 */
object Test3 {

 def main(args: Array[ String ]) {
  val conf = new SparkConf().setAppName("ScalaTest").setMaster("local")

  val sc = new SparkContext(conf)
  val rddInt: RDD[ Int ] = sc.parallelize(List(1, 2, 3, 4, 5), 3)
  //定义一个Int类型的List,初始值为:1~5,分布在3个分区上


val rddAggr1: (Int, Int) =
   rddInt.aggregate((0, 0))((x, y) => (x._1 + y, x._2 + 1), (x, y) => (x._1 + y._1, x._2 + y._2))
  //( o )?)一看懵了,我们分开来,一个一个看,就比较好理解了:
//aggregate 返回一个2元组,元组内第一个值为List中所有数据求和,第二个值为List中的数据个数
//aggregate 其中(0,0) Int二元组,是参与计算的初始值
// 第一个0是参与求和的初始值,第二个0是参与求个数的初始值

//((x, y) => (x._1 + y, x._2 + 1), (x, y) => (x._1 + y._1, x._2 + y._2))分成两部分看:
//(x, y) => (x._1 + y, x._2 + 1) 单线程求和过程;
//(x, y) => (x._1 + y._1, x._2 + y._2) 各分区求和过程;
// (x, y) => (x._1 + y, x._2 + 1)理解如下:
//x._1为元组的第一个值,yList中的各个值
//x._2为元组的第二个值,1为每次加1
  //计算过程:
//x._1 + y 取元组(0,0)中 的第一个值0作为加数,与List中的第一个值1作为被加数相加,得到结果1//x._2 + 1 取元组(0,0)中的第二个值0作为加数,1作为被加数,得到结果1//以上两结果构成新元组(1,1),再以元组(1,1)List中第二个值2求和(1+2=3,1+1=2//得到又一个新元组(3,2),以此类推,计算完所有数据求和,得到最终元组(15,5)

  //(x, y) => (x._1 + y._1, x._2 + y._2)理解如下:
//以上求和过程为单线程计算过程,实际spark执行是分布式的
// 即,可能会把Lit(1,2,3,4,5)分为多个区,如:P1(1,2),P2(3,4),P3(5)
  //各区计算结果:(3,2),(7,2),(5,1)
  //每个区以单线程方式计算结果,最后再将各个区的计算结果合并
//(x, y) => (x._1 + y._1, x._2 + y._2)为每个区的计算结果元组相加
// 即,(3+7+5,2+2+1)得到(15,5)作为最终返回的二元组
//这里的x,y与前面的x,y没有关系
//此处的x._1可以理解为第一个分区的计算结果二元组的第一个值,x._2第二个值
//y._1y._2可以理解为第二个分区的计算结果二元组的两个值
// 两个分区的计算结果合并后,作为新的元组,再与第三个分区合并,得到最终结果

println("rddAggr1:" + rddAggr1) // (15,5)
  //理解了上面的过程,改成下面的计算就更清楚了(列表中数据乘积,并求个数)
val rddAggr2: (Int, Int) =
  rddInt.aggregate((1, 0))((x, y) => (x._1 * y, x._2 + 1), (x, y) => (x._1 * y._1, x._2 + y._2))

  println("rddAggr2:" + rddAggr2) // (120,5)
}
}

猜你喜欢

转载自lguan.iteye.com/blog/2319917