Spark:如何将RDD [T]`拆分为Seq [RDD [T]]并保留排序

时间:2014-11-12 21:08:48

标签: scala apache-spark spark-streaming rdd

如何有效地将RDD[T]拆分为Seq[RDD[T]] / Iterable[RDD[T]] n元素并保留原始排序?

我希望能够写出像这样的东西

RDD(1, 2, 3, 4, 5, 6, 7, 8, 9).split(3)

应该会产生类似

的内容
Seq(RDD(1, 2, 3), RDD(4, 5, 6), RDD(7, 8, 9))

spark是否提供了这样的功能?如果不是什么是实现这一目标的高效方法?

val parts = rdd.length / n
val rdds = rdd.zipWithIndex().map{ case (t, i) => (i - (i % parts), t)}.groupByKey().values.map(iter => sc.parallelize(iter.toSeq)).collect

看起来不是很快......

1 个答案:

答案 0 :(得分:0)

从技术上讲,你可以做你所建议的事情。但是,在利用计算集群执行大数据的分布式处理的情况下,它确实没有意义。首先,它与Spark的整个观点背道而驰。如果您执行groupByKey然后尝试将它们提取到单独的RDD中,则可以有效地将RDD中分发的所有数据提取到驱动程序上,然后将每个数据重新分发回群集。如果驱动程序无法加载整个数据文件,则它也无法执行此操作。

您不应该从本地文件系统将大型数据文件加载到驱动程序节点上。您应该将文件移动到HDFS或S3等分布式文件系统上。然后,您可以通过val lines = SparkContext.textFile(...)将单个大数据文件加载到集群中,并将其加载到RDD行中。执行此操作时,群集中的每个工作人员将只加载文件的一部分,这可以完成,因为数据已经分布在分布式文件系统中的群集中。

如果您需要将数据组织成对数据功能处理很重要的“批次”,您可以使用适当的批次标识符键入数据,例如:val batches = lines.keyBy( line => lineBatchID(line) )

然后可以将每个批次缩减为批次级摘要,这些摘要可以缩减为单个总体结果。

为了测试Spark代码,可以将数据文件的 small 样本加载到单个机器上。但是当谈到完整数据集时,您应该利用分布式文件系统和spark集群来处理这些数据。