Spark:如何扫描' RDD收藏?

时间:2015-01-22 11:30:44

标签: scala apache-spark

Spark是否有任何模拟Scala scan操作来处理RDD集合? (详情请见Reduce, fold or scan (Left/Right)?

例如:

val abc = List("A", "B", "C")

def add(res: String, x: String) = { 
  println(s"op: $res + $x = ${res + x}")
  res + x
} 

所以得到:

abc.scanLeft("z")(add)
// op: z + A = zA      // same operations as foldLeft above...
// op: zA + B = zAB
// op: zAB + C = zABC
// res: List[String] = List(z, zA, zAB, zABC) // maps intermediate results

任何其他方法可以达到相同的效果吗?

更新

什么是“Spark”解决方法,例如,以下问题:

将向量的元素计算为(在伪代码中):

x(i) = SomeFun(for k from 0 to i-1)(y(k)) 

我应该collect RDD吗?别无他法?

更新2

好的,我理解一般问题。然而,也许你可以就我必须处理的具体案例向我提出建议。

我有一个int作为输入RDD的列表,我必须构建一个outptut RDD,其中应该包含以下内容:

1) input.length == output.length // output list is of the same length as input

2) output(i) = sum( range (0..i), input(i)) / q^i // i-th element of output list equals sum of input elements from 0 to i divided by i-th power of some constant q   

事实上,我需要mapfold功能的组合来解决这个问题。

另一个想法是在输入列表的缩小尾部上写一个递归fold。但这样效率极低,AFAIK Spark没有RDD的tailinit功能。

你如何在Sparck中解决这个问题?

1 个答案:

答案 0 :(得分:2)

你是正确的,在通用RDD中不存在scan()的模拟。

可能的解释:这种方法需要访问分布式集合的所有元素来处理生成的输出集合的每个元素。在继续下一个输出元素之前。

因此,如果你的输入列表是100万加一个条目,那么集群上将有 100万个shuffle操作(即使这里不需要排序 - spark给它“免费”时做集群收集步骤。)

更新 OP扩大了问题。以下是对扩展问题的回应。

来自更新的OP:

x(i) = SomeFun(for k from 0 to i-1)(y(k)) 

你需要区分x(i)计算 - 特别是y(k)函数 - 是否会:

  • 需要访问整个数据集x(0 .. i -1)
  • 更改数据集的结构

每次迭代。 扫描的情况 - 并且根据您的描述,它似乎是您的目的。 Spark不支持AFAIK。再一次 - 想想你是否在开发分布式框架。 如何实现同样的目标?它似乎不是一种可扩展的手段 - 所以是的,你需要在

中进行计算
collect()

对原始RDD的调用并在驱动程序上执行。