Apache spark Spark RDD上的Lazy foreach

Apache spark Spark RDD上的Lazy foreach,apache-spark,rdd,lazy-sequences,Apache Spark,Rdd,Lazy Sequences,我有一个很大的RDD字符串(通过几个sc.textFile(…)的并集获得) 现在,我想在RDD中搜索给定的字符串,并希望在找到“足够好”匹配时停止搜索 为此,我可以改装foreach,或filter,或map,但所有这些都将迭代该RDD中的每个元素,无论是否已达到匹配 有没有办法缩短这个过程并避免重复整个RDD?没有。没有find方法,就像在激发Spark API的Scala集合中一样,一旦找到满足谓词的元素,就会停止查找。可能您最好的选择是使用一个可以最小化多余扫描的数据源,比如Cassan

我有一个很大的RDD字符串(通过几个
sc.textFile(…)的并集获得)

现在,我想在RDD中搜索给定的字符串,并希望在找到“足够好”匹配时停止搜索

为此,我可以改装
foreach
,或
filter
,或
map
,但所有这些都将迭代该RDD中的每个元素,无论是否已达到匹配


有没有办法缩短这个过程并避免重复整个RDD?

没有。没有
find
方法,就像在激发Spark API的Scala集合中一样,一旦找到满足谓词的元素,就会停止查找。可能您最好的选择是使用一个可以最小化多余扫描的数据源,比如Cassandra,在Cassandra中,驱动程序按下一些查询参数。您还可以看看更具实验性的伯克利项目BlinkDB

总而言之,Spark的设计更多地是为了扫描数据集,比如之前的MapReduce,而不是传统的数据库查询

我可以为此改装foreach、filter或map,但所有这些都将遍历RDD中的每个元素

事实上,你错了。如果您限制结果(使用
take
first
),Spark engine足够智能,可以优化计算:

现在让我们检查accum:

>>> print("Checked {0} items, found {1}".format(acc.value, x))
Checked 6 items, found 7109
为了确保一切都按预期进行:

acc = sc.accumulator(0)
rdd.filter(lambda x: good_enough(x, 100000)).take(1)
assert acc.value == rdd.count()
同样的事情也可以通过使用数据帧和udf以更有效的方式完成


注意:在某些情况下,甚至可以在Spark中使用无限序列,但仍然可以得到结果。您可以查看我的答案,以获取一个示例。

据我所知,RDD的行为实际上更像Scala惰性集合。如果您有任何意见,请检查并让我知道。
acc = sc.accumulator(0)
rdd.filter(lambda x: good_enough(x, 100000)).take(1)
assert acc.value == rdd.count()