spark源码action系列-collect

RDD.collect的操作

collect操作,在最后的ResultTask.runTask,执行的function的操作为下面代码.

由于对ResultTask的runTask这个函数的返回值就是这个runTask函数在执行完成RDD传入的function后的返回值.这里要说明下如果task的结果超过了spark.driver.maxResultSize配置的最大值时,默认是1G,直接对task的结果进行丢掉,不处理,

def collect(): Array[T] = withScope {
  val results = sc.runJob(this(iter: Iterator[T]) => iter.toArray)

这个操作把所有的task返回的array进行连接,合并到一个array中进行返回.
  Array.concat(results: _*)
}

 

用于在driver端处理各个Task的结果返回的resultHandler函数,这个函数就是把对应的task的结果直接放到driver端接收数据的一个数组中.

val results = new Array[U](partitions.size)

(index, res) => results(index) = res

在这个操作中,是直接把每个partitionIterator的结果转换成一个array.上面的红色部分((iter: Iterator[T]) => iter.toArray).

从上面的代码中可以看出来,针对一个rdd的collect的操作是把当前的rdd中所有的partition中的数据集的iterator直接转换成一个array[T],这个array也是对应此partition的返回值,使用collect时要确保每个task的返回的数据的大小,同时要保证所有的task中返回的数据的大小不能超过1GB.

在driver端接收到每一个task返回的数据集时,每个task返回的是这个task中所有的数据集的数组,通过在driver端定义的一个results数组,这个数组的长度就是partition的个数,每个task的返回结果存储到这个对应的index位置上((index, res) => results(index) = res),最后在把这个二维的数据进行concat操作(  Array.concat(results: _*)),把所有的数据集合并到一个数组中.这个数组就是执行collect的最终的返回值.

你可能感兴趣的:(spark源码分析,spark-transform)