Spark 如何驱逐缓存的分区?

Posted

技术标签:

【中文标题】Spark 如何驱逐缓存的分区?【英文标题】:How does Spark evict cached partitions? 【发布时间】:2017-03-07 23:36:40 【问题描述】:

我在独立模式下运行 Spark 2.0,并且我是集群中唯一提交作业的人。

假设我有一个包含 100 个分区的 RDD,并且一次总共只能容纳 10 个分区。

我们还假设分配的执行内存足够并且不会干扰存储内存。

假设我遍历该 RDD 中的数据。

rdd.persist()  // MEMORY_ONLY

for (_ <- 0 until 10) 
  rdd.map(...).reduce(...)


rdd.unpersist()

对于每次迭代,在rdd.unpersist()之前持久化的前 10 个分区会一直在内存中吗?

【问题讨论】:

【参考方案1】:

目前我所知道的,Spark 对 RDD 分区默认使用 LRU(最近较少使用)驱逐策略。他们正在努力添加新策略。 https://issues.apache.org/jira/browse/SPARK-14289

此策略删除最近较少使用的元素 最后使用的时间戳在将元素放入缓存或从缓存中检索元素时更新。

我想你的内存中总会有 10 个分区,但哪些存储在内存中,哪些会被驱逐取决于它们的使用情况。根据Apache FAQ:

同样,不适合内存的缓存数据集也会溢出 磁盘或在需要时动态重新计算,由 RDD 的存储级别。

因此,其他分区是否溢出到磁盘或动态重新计算取决于您的配置。重新计算是默认设置,这并不总是最有效的选择。您可以将数据集的存储级别设置为 MEMORY_AND_DISK 以避免这种情况。

【讨论】:

谢谢。根据我的理解和您包含的 JIRA 链接,LRU 主要涉及缓存的不同 RDD。这里我想知道数据分区不能完全包含在内存中的单个RDD会发生什么。 据我了解,无论您有单个 RDD 还是多个 RDD,都适用相同的技术。 JIRA 链接中的评论让我很困扰。 “默认的 RDD 驱逐策略是 LRU(带有一个附加规则,即不替换属于同一 RDD 的另一个块,如当前创建的分区)。”我又挖了一点,我相信分区不会被驱逐来为同一个 RDD 中的其他分区让路。不过感谢您的指点!【参考方案2】:

我想我找到了答案,所以我要回答我自己的问题。

驱逐策略似乎在MemoryStore 类中。这是source code。

似乎没有驱逐条目来为同一 RDD 中的条目腾出位置。

【讨论】:

你知道为什么“它需要从同一个 RDD 中替换另一个块(这会导致我们想要避免的不适合内存的 RDD 的循环替换模式浪费)。”?

以上是关于Spark 如何驱逐缓存的分区?的主要内容,如果未能解决你的问题,请参考以下文章

点网内存缓存驱逐

Spark RDD在Spark中的地位和作用如何?

Spark RDD在Spark中的地位和作用如何?

Spark RDD在Spark中的地位和作用如何?

Spark读取HDFS数据分区参考

Spark框架—RDD分区和缓存