在spark中使用join()时重复值

时间:2016-01-18 23:02:29

标签: scala apache-spark

我目前正在编写一个程序,我决定是使用groupByKey,然后是连接还是只是一个连接。

基本上我有一个RDD,每个键有很多值,另一个RDD每个键只有一个值,但是这个值非常大。我的问题是当我将这些值加在一起时,会产生很多大值的副本(一个用于每个较小值的单个实例)或者只能保留一个大值的副本,同时提供对所有值的引用原始价值观。

基本上我有这样的情况:

val InvIndexes:RDD[(Int,InvertedIndex)] //InvertedIndex is very large
val partitionedVectors:RDD[(Int, Vector)]

val partitionedTasks:RDD[(Int, (Iterator[Vector], InvertedIndex))] = partitionedvectors.groupByKey().join(invIndexes)


val similarities = partitionedTasks.map(//calculate similarities)

我的问题是,在执行此操作之前,代码之间是否存在任何重大的空间复杂性差异:

val InvIndexes:RDD[(Int,InvertedIndex)]
val partitionedVectors:RDD[(Int, Vector)]

val partitionedTasks:RDD[(Int, (Vector, InvertedIndex))] = partitionedvectors.join(invIndexes)

val similarities = partitionedTasks.map(//calculate similarities)

1 个答案:

答案 0 :(得分:1)

从技术上讲,应该没有复制。 join基本上是cogroup,后跟flatMapValues,具有嵌套的for理解。假设单个共同分组元素如下所示:

val pair = (1, (
  Seq(Vectors.dense(Array(1.0)), Vectors.dense(Array(2.0))),
  Seq(Vectors.dense(Array(3.0)), Vectors.dense(Array(4.0)))
))

后续操作相当于:

val result = pair match {
  case (k, (xs, ys)) => xs.flatMap(x => ys.map(y => (k, (x, y))))
}

并且不会复制预期的矢量:

require(result(0)._2._1 eq result(1)._2._1)

只要数据在内存中处理或整个分区被序列化/反序列化(例如在collect中),就应保留此状态,但我个人不会依赖于此。即使您忽略了低级别的实现细节,简单的shuffle也可能需要完整的副本。