用于巨大列表的Spark FlatMap函数

时间:2015-07-04 11:53:07

标签: mapreduce apache-spark

我有一个非常基本的问题。 Spark的flatMap功能允许您为每个输入发出0,1或更多输出。因此,您提供给flatMap的(lambda)函数应该返回一个列表。

我的问题是:如果此列表太大而无法处理内存,会发生什么?

我目前还没有实现这个问题,在我重写MapReduce软件之前应该先解决这个问题,这可以通过将context.write()放在我想要的算法的任何地方来轻松解决这个问题。 (单个映射器的输出可能很容易很多千兆字节。

如果您感兴趣:映射器会执行某种字数统计,但事实上它会生成所有可能的子字符串,以及与文本匹配的各种正则表达式。 (生物信息学用例)

1 个答案:

答案 0 :(得分:5)

  

因此,您提供给flatMap的(lambda)函数应该返回一个列表。

不,它不必返回列表。在实践中,您可以轻松使用惰性序列。在查看Scala RDD.flatMap签名时,可能更容易发现:

flatMap[U](f: (T) ⇒ TraversableOnce[U])

由于TraversableOnce的子类包括SeqViewStream,您可以使用延迟序列而不是List。例如:

val rdd = sc.parallelize("foo" :: "bar" :: Nil)
rdd.flatMap {x => (1 to 1000000000).view.map {
    _ => (x, scala.util.Random.nextLong)
}}

既然你已经提到了lambda函数,我假设你正在使用PySpark。您可以做的最简单的事情是返回generator而不是列表:

import numpy as np

rdd = sc.parallelize(["foo", "bar"])
rdd.flatMap(lambda x: ((x, np.random.randint(1000)) for _ in xrange(100000000)))

由于RDDs被懒惰地评估,甚至可以从flatMap返回无限序列。使用一点toolz幂:

from toolz.itertoolz import iterate
def inc(x):
    return x + 1

rdd.flatMap(lambda x: ((i, x) for i in iterate(inc, 0))).take(1)