为什么我必须明确告诉Spark要缓存什么?

时间:2015-12-06 12:33:36

标签: apache-spark caching

在Spark中,每次我们对RDD执行任何操作时,都会重新计算RDD。因此,如果我们知道RDD将被重用,我们应该明确地缓存RDD。

让我们说,Spark决定懒惰地缓存所有RDD并使用LRU自动将最相关的RDD保存在内存中(这是大多数缓存以任何方式工作的方式)。这对开发人员有很大的帮助,因为他不必考虑缓存并专注于应用程序。此外,我不知道它如何对性能产生负面影响,因为很难跟踪程序内变量(RDD)的使用次数,大多数程序员将决定以任何方式缓存大多数RDD。

缓存通常会自动发生。以OS /平台或框架或工具为例。但是由于分布式计算中缓存的复杂性,我可能会忽略为什么缓存不能自动或性能影响。

所以我无法理解,为什么我必须显式缓存为,

  1. 看起来很难看
  2. 很容易错过
  3. 可以轻松过度使用

1 个答案:

答案 0 :(得分:13)

主观的理由清单:

  • 在实践中很少需要缓存,主要用于迭代算法,打破长谱系。例如,典型的ETL管道可能根本不需要缓存。 缓存大多数RDD 绝对不是正确的选择。
  • 没有通用的缓存策略。实际选择取决于可用的资源,如内存量,磁盘(本地,远程,存储服务),文件系统(内存,磁盘)和特定应用程序。
  • 磁盘上持久性很昂贵,内存持久性会给JVM带来更多压力,并且正在使用Spark中最有价值的资源
  • 在不对应用语义进行假设的情况下自动缓存是不可能的。特别是:

    • 数据源更改时的预期行为。没有通用答案,在许多情况下,无法自动跟踪更改
    • 区分确定性和非确定性转换以及在缓存和重新计算之间进行选择
  • 将Spark缓存与OS级别缓存进行比较并不合理。操作系统缓存的主要目标是减少延迟。在Spark中,延迟通常不是最重要的因素,缓存用于其他目的,如一致性,正确性和减少系统不同部分的压力。
  • 如果缓存没有使用堆外存储,那么缓存会给垃圾收集器带来额外的压力。 GC成本实际上可能高于重新计算数据的成本。
  • 取决于数据和缓存方法,从缓存中读取数据的内存效率会明显降低。
  • 缓存会干扰Spark SQL中可用的更高级优化,从而有效地禁用分区修剪或谓词和投影下推。

值得注意的是:

  • 使用LRU
  • 自动处理删除缓存数据
  • 一些数据(如中间shuffle数据)会自动保留。我承认它使以前的一些论点至少部分无效。
  • Spark缓存不会影响系统级别或JVM级别机制