【问题标题】:Why do I have to explicitly tell Spark what to cache?为什么我必须明确告诉 Spark 缓存什么?
【发布时间】:2016-03-11 02:31:40
【问题描述】:

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

假设,Spark 决定延迟缓存所有 RDD,并使用 LRU 将最相关的 RDD 自动保存在内存中(这是大多数缓存的工作方式)。这将对开发人员有很大帮助,因为他不必考虑缓存并专注于应用程序。此外,我看不出它会对性能产生什么负面影响,因为很难跟踪变量(RDD)在程序中使用了多少次,大多数程序员会决定以任何方式缓存大部分 RDD。

缓存通常自动发生。以操作系统/平台或框架或工具为例。但是由于分布式计算中缓存的复杂性,我可能会错过为什么缓存不能自动进行或对性能的影响。

所以我不明白,为什么我必须明确缓存为,

  1. 看起来很丑
  2. 很容易错过
  3. 很容易过度/不足使用

【问题讨论】:

    标签: apache-spark caching


    【解决方案1】:

    主观原因列表:

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

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

    另外值得注意的是:

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

    【讨论】:

    • 我不同意“很少需要缓存”的理由。到目前为止,OS 或 API 之类的文件读取都负责缓存,因此我们不必为此烦恼。但是对于任何重要的应用程序,缓存几乎总是强制性的。
    • 并非如此。尤其是基于磁盘的存储重新计算可能比缓存更便宜。
    • 这不是真的@rakesh!在这些情况下,这不是强制性的。这个答案中讨论的原因完全有效。请记住,Spark 不是内存数据存储,也不是缓存系统。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2014-05-01
    相关资源
    最近更新 更多