reduce操作在RDD中属于action操作,伴随着sc.runJob的调用,源码如下(基于spark 1.2.0版本):
def reduce(f: (T, T) => T): T = {
val cleanF = sc.clean(f)
val reducePartition: Iterator[T] => Option[T] = iter => {
if (iter.hasNext) {
Some(iter.reduceLeft(cleanF)) //一个一个迭代,从左开始
} else {
None
}
}
var jobResult: Option[T] = None
val mergeResult = (index: Int, taskResult: Option[T]) => { //当每个任务执行完后,都会返回一个这样的结果,index为分区的索引
if (taskResult.isDefined) {
jobResult = jobResult match {
case Some(value) => Some(f(value, taskResult.get)) //第二个分区的结果与第一个分区的一起,再用f处理
case None => taskResult //当第一个任务完成时,会进入,taskResult 为第一个分区的结果
}
}
}
sc.runJob(this, reducePartition, mergeResult) //任务的执行
/