为什么在Spark中懒惰地评估persist()

时间:2015-12-23 15:16:51

标签: scala apache-spark

我理解在Scala中有两种类型的操作

  1. 转换
  2. 操作
  3. 像map(),filter()这样的转换是懒惰的。因此,可以在Action执行上完成该优化。例如,如果我执行action first(),那么Spark将优化为只读取第一行。

    但为什么延迟评估persist()操作。因为无论我采取哪种方式,热切地或懒惰地,它都将按照存储级别保持整个RDD。

    请您详细说明为什么persist()是转换而不是行动。

3 个答案:

答案 0 :(得分:9)

对于初学者来说,渴望持久会污染整个管道。 cachepersist仅表达意图。这并不意味着我们将在RDD实现并且可以实际缓存时达到目的。此外,存在自动缓存数据的上下文。

  

因为无论我采取哪种方式,急切地或懒惰地,它都会按照存储级别保留整个RDD。

这不完全正确。事实是,persist不是持久的。正如MEMORY_ONLY持久性级别明确指出in the documentation

  

如果RDD不适合内存,则某些分区将不会被缓存,并且每次需要时都会重新计算。

MEMORY_AND_DISK剩余数据存储到磁盘,但如果没有足够的内存用于后续缓存,则仍可以将其驱逐。更重要的是:

  

Spark会自动监控每个节点上的缓存使用情况,并以最近最少使用(LRU)的方式删除旧数据分区。

您还可以认为cache / persist在语义上与为特定IO副作用执行的Spark操作不同。 cache更像是一个Spark引擎的提示,我们可能希望以后重用这段代码。

答案 1 :(得分:5)

如果您有一些可能会或可能不会使用的数据,那么使persist()渴望的效率会很低。正常的Spark转换对应于Scala中的def。持久性将其转换为lazy val

答案 2 :(得分:0)

persist是令人困惑的名称,因为它不会超出您的上下文生命周期。

persist与缓存相同。数据在第一次计算时被缓存,这样如果在另一个计算中使用RDD,则不会重新计算结果。