【问题标题】:Is Spark RDD cached on worker node or driver node (or both)?Spark RDD 是否缓存在工作节点或驱动节点(或两者)上?
【发布时间】:2017-01-04 22:10:23
【问题描述】:

谁能纠正我对 Spark 坚持的理解。

如果我们在一个 RDD 上执行了 cache() ,它的值只缓存在那些最初计算 RDD 的节点上。 意思是,如果有 100 个节点的集群,并且 RDD 是在第一个和第二个节点的分区中计算的。如果我们缓存了这个 RDD,那么 Spark 只会在第一个或第二个工作节点中缓存它的值。 所以当这个 Spark 应用程序在后期尝试使用这个 RDD 时,Spark 驱动程序必须从第一个/第二个节点获取值。

我说的对吗?

(或)

RDD 值是否持久保存在驱动程序内存中而不是节点上?

【问题讨论】:

    标签: apache-spark apache-spark-sql rdd


    【解决方案1】:

    改变这个:

    那么 Spark 将仅在第一个 第二个工作节点中缓存其值。

    到这里:

    那么 Spark 将仅在第一个 第二个工作节点中缓存其值。

    并且...是的正确!

    Spark 尝试最小化内存使用量(我们喜欢它!),因此它不会产生任何不必要的内存负载,因为它懒惰地评估每个语句,即它不会对任何转换做任何实际工作,它会等待一个动作发生,这让Spark别无选择,而不是做实际工作(读取文件,沟通例如,将数据传输到网络,进行计算,将结果收集回驱动程序..)。

    您知道,我们不想缓存所有内容,除非我们真的可以(即内存容量允许这样做(是的,我们可以在执行程序或/和驱动程序中请求更多内存,但有时我们的集群只是没有资源,当我们处理大数据时真的很常见)而且它真的很有意义,即缓存的RDD将被一次又一次地使用(所以缓存它会加速执行我们的工作)。

    这就是为什么你想unpersist()你的RDD,当你不再需要它时......! :)

    查看这张图片,来自我的一项工作,我请求了 100 个执行器,但是执行器选项卡显示 101,即 100 个从属/工作人员和一个主/驱动程序:

    【讨论】:

    • 我想我必须这样提出我的问题。当我们选择 RDD.cache().... Spark 是将 RDD 缓存在驱动内存还是执行内存?
    • @Ramesh 在使用它的执行者中。想象一下,驱动程序必须缓存我的 RDD,其中包含 15T 的数据。这将是一场灾难! ;)
    • @gsamaras 感谢您的回答。如果 RDD 最初是在 100 个 executor 中计算的,我们缓存了它,这是否意味着这 100 个 executor 被占用并且不能再被任何其他 Spark 应用程序使用?如果我们想允许其他应用程序在其中运行任务,我们必须做.unpersist?为什么持有(即cache)一些内存资源会阻止其他应用程序利用 cpu 计算资源?这不是一个不明智的策略吗?谢谢
    【解决方案2】:

    RDD.cache 是一个惰性操作。除非您调用计数之类的操作,否则它什么也不做。调用该操作后,该操作将使用缓存。它只会从缓存中获取数据并执行操作。

    RDD.cache- 以默认存储级别(仅限内存)持久保存 RDD。 Spark RDD API

    2.RDD值是否持久化在驱动内存而不是节点上?

    RDD 也可以持久化到磁盘和内存中。单击指向 Spark 文档的链接以获取所有选项 Spark Rdd Persist

    【讨论】:

      【解决方案3】:
      # no actual caching at the end of this statement
      rdd1=sc.read('myfile.json').rdd.map(lambda row: myfunc(row)).cache()
      
      # again, no actual caching yet, because Spark is lazy, and won't evaluate anything unless
      # a reduction op
      rdd2=rdd2.map(mysecondfunc)
      
      # caching is done on this reduce operation. Result of rdd1 will be cached in the memory of each worker node
      n=rdd1.count()
      

      所以回答你的问题

      如果我们在 RDD 上执行了 cache(),它的值只会缓存在那些最初计算 RDD 的节点上

      缓存某些东西的唯一可能性是在工作节点上,而不是在驱动节点上。

      cache 函数只能应用于RDD (refer),并且由于RDD 仅存在于工作节点的内存中(弹性分布式 数据集!),它的结果缓存在相应的工作节点内存中。一旦你应用了像count 这样的操作,它将结果返回给驱动程序,它就不再是真正的RDD,它只是工作节点在各自内存中进行 RDD 计算的结果

      由于上例中的cache 是在多个工作节点上的rdd2 上调用的,因此缓存只发生在工作节点的内存上。

      在上面的例子中,当再次对rdd1做一些map-red操作时,它不会再次读取JSON,因为它被缓存了

      仅供参考,我使用memory 这个词是基于缓存级别设置为MEMORY_ONLY 的假设。当然,如果该级别更改为其他级别,Spark 将根据设置缓存到memorystorage

      【讨论】:

        【解决方案4】:

        这是关于缓存的一个很好的答案

        (Why) do we need to call cache or persist on a RDD

        基本上缓存将 RDD 存储在该节点的内存/磁盘(基于持久性级别集)中,因此当再次调用此 RDD 时,它不需要重新计算其沿袭(沿袭 - 执行到的先前转换集处于当前状态)。

        【讨论】:

        • 我问这个问题的原因是..如果我坚持(仅限内存)一个 RDD,Spark 会将其缓存在内存中,为此执行 Spark 将占用 3 到 4 倍的内存RDD 大小。
        • 例如,如果有一个 300MB 的 RDD 文件,如果我们持久化它,Spark 将使用将近 1GB 的内存来持久化它。所以正因为如此,有时它会抛出内存异常 Java Heap size 问题。要修复它,我认为我们需要为驱动程序内存分配适当的内存,即明确超过 1GB。所以这就是我问缓存/持久化是否直接影响驱动程序内存的原因。
        • 当我说“RDD 值是否保留在驱动程序内存中而不是节点上?”我的意思是说“Spark 是否会将值缓存在驱动程序内存或工作节点内存中(内存)”?
        • 我想我可以这样简单地提出我的问题。当我们选择 RDD.cache().... Spark 是将 RDD 缓存在驱动内存还是执行内存?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 2019-02-24
        • 1970-01-01
        • 2016-09-06
        • 2019-05-21
        • 1970-01-01
        相关资源
        最近更新 更多