我理解在Scala中有两种类型的操作
像map(),filter()这样的转换是懒惰的。因此,可以在Action执行上完成该优化。例如,如果我执行action first(),那么Spark将优化为只读取第一行。
但为什么延迟评估persist()操作。因为无论我采取哪种方式,热切地或懒惰地,它都将按照存储级别保持整个RDD。
请您详细说明为什么persist()是转换而不是行动。
答案 0 :(得分:9)
对于初学者来说,渴望持久会污染整个管道。 cache
或persist
仅表达意图。这并不意味着我们将在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,则不会重新计算结果。