我如何强制Spark执行对map的调用,即使它认为由于其懒惰的评估而不需要执行它?
我试图将cache()
与地图调用放在一起,但仍然无法解决问题。我的map方法实际上将结果上传到HDFS。所以,它并非无用,但Spark认为它是。
答案 0 :(得分:33)
简答:
要强制Spark执行转换,您需要获得结果。有时,简单的count
操作就足够了。
<强> TL; DR:强>
好的,让我们查看 RDD
操作。
RDD
支持两种类型的操作:
例如,map
是一个转换,它通过一个函数传递每个数据集元素,并返回一个表示结果的新RDD。另一方面,reduce
是一个动作,它使用某个函数聚合RDD的所有元素,并将最终结果返回给驱动程序(尽管还有一个返回分布式数据集的并行reduceByKey
)。
Spark中的所有转换都是 lazy ,因为它们不会立即计算结果。
相反,他们只记得应用于某些基础数据集(例如文件)的转换。 仅当操作需要将结果 返回到驱动程序时才会计算转换。这种设计使Spark能够更有效地运行 - 例如,我们可以意识到通过map创建的数据集将用于reduce,并且只将reduce的结果返回给驱动程序,而不是更大的映射数据集。
默认情况下,每次对其执行操作时,可能会重新计算每个已转换的RDD
。但是,您也可以使用RDD
(或persist
)方法在内存中保留cache
,在这种情况下,Spark会在群集上保留元素,以便下次更快地访问你查询它。还支持在磁盘上保留RDD
或在多个节点上复制。
要强制Spark执行对map的调用,您需要获得结果。有时count
行动就足够了。
答案 1 :(得分:14)
Spark transformations仅描述必须完成的工作。要触发执行,您需要action。
在您的情况下,存在更深层次的问题。如果目标是创建某种副作用,例如在HDFS上存储数据,则使用正确的方法是foreach
。它既是一个动作又具有干净的语义。同样重要的是,与map
不同,它并不意味着引用透明度。