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

rak*_*esh 5 caching apache-spark

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

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

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

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

  1. 它看起来很难看
  2. 它很容易被遗漏
  3. 它可以很容易地使用过度/不足

zer*_*323 15

一个主观的原因列表:

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

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

还值得注意的是:

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