RDD在内存中保留多长时间?

时间:2017-03-31 11:22:51

标签: apache-spark rdd

考虑到内存受限,我觉得spark会自动从每个节点中删除RDD。我想知道这个时间是可配置的吗? spark如何决定何时从内存中驱逐RDD

注意:我不是在谈论rdd.cache()

4 个答案:

答案 0 :(得分:7)

  

我想知道这次是可配置的吗?火花如何决定何时   从内存中驱逐RDD

RDD就像任何其他对象一样。如果你不持久/缓存它,它将作为托管语言下的任何其他对象,并且一旦没有指向它的活动根对象就被收集。

@Jacek指出的“如何”部分是一个名为ContextCleaner的对象的责任。主要是,如果您需要详细信息,this is what the cleaning method looks like

private def keepCleaning(): Unit = Utils.tryOrStopSparkContext(sc) {
  while (!stopped) {
    try {
      val reference = Option(referenceQueue.remove(ContextCleaner.REF_QUEUE_POLL_TIMEOUT))
          .map(_.asInstanceOf[CleanupTaskWeakReference])
      // Synchronize here to avoid being interrupted on stop()
      synchronized {
        reference.foreach { ref =>
          logDebug("Got cleaning task " + ref.task)
          referenceBuffer.remove(ref)
          ref.task match {
            case CleanRDD(rddId) =>
              doCleanupRDD(rddId, blocking = blockOnCleanupTasks)
            case CleanShuffle(shuffleId) =>
              doCleanupShuffle(shuffleId, blocking = blockOnShuffleCleanupTasks)
            case CleanBroadcast(broadcastId) =>
              doCleanupBroadcast(broadcastId, blocking = blockOnCleanupTasks)
            case CleanAccum(accId) =>
              doCleanupAccum(accId, blocking = blockOnCleanupTasks)
            case CleanCheckpoint(rddId) =>
              doCleanCheckpoint(rddId)
            }
          }
        }
      } catch {
        case ie: InterruptedException if stopped => // ignore
        case e: Exception => logError("Error in cleaning thread", e)
    }
  }
}

如果你想了解更多信息,我建议浏览Sparks来源,甚至更好,阅读@Jacek书籍"Mastering Apache Spark"This points to an explanation regarding ContextCleaner

答案 1 :(得分:5)

一般情况下,Yuval Itzchakov wrote"就像其他任何对象一样,但是......(总是"但是&# 34;,不是吗?

在Spark中,由于我们有shuffle块(在Spark管理的其他块中),因此并不那么明显。它们由运行在执行程序上的BlockManagers管理。当驱动程序上的对象被驱逐出内存时,它们必须以某种方式得到通知,对吗?

ContextCleaner 即将到来的地方。它是Spark应用程序的垃圾收集器,负责应用程序范围内的shuffle,RDD,广播,累加器和检查点RDD的清理,旨在减少长时间运行的数据繁重的Spark应用程序的内存需求。

ContextCleaner在驱动程序上运行。它是在SparkContext启动时创建并立即启动的(并且启用了spark.cleaner.referenceTracking Spark属性,默认情况下是这样)。它在SparkContext停止时停止。

通过使用jconsolejstack转储Spark应用程序中的所有线程,您可以看到它正常工作。 ContextCleaner使用守护进程 Spark Context Cleaner 线程清除RDD,shuffle和广播状态。

您还可以通过为INFO记录器启用DEBUGorg.apache.spark.ContextCleaner日志记录级别来查看其工作。只需将以下行添加到conf/log4j.properties

log4j.logger.org.apache.spark.ContextCleaner=DEBUG

答案 2 :(得分:1)

测量GC的影响

GC调整的第一步是收集有关垃圾收集发生频率和GC使用时间的统计信息。这可以通过将-verbose:gc -XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps添加到Java选项来完成。 (有关将Java选项传递给Spark作业的信息,请参阅配置指南。)下次运行Spark作业时,每次发生垃圾收集时,您都会看到工作日志中打印的消息。请注意,这些日志将位于群集的工作节点上(在其工作目录中的stdout文件中),而不是在驱动程序上。

高级GC调整

为了进一步调整垃圾收集,我们首先需要了解JVM中有关内存管理的一些基本信息:

Java堆空间分为Young和Old两个区域。年轻一代意味着持有短命物体,而老一代则用于生命周期较长的物体。

年轻一代进一步分为三个区域[Eden,Survivor1,Survivor2]。

垃圾收集过程的简化描述:当Eden已满时,在Eden上运行次要GC,并将从Eden和Survivor1中存活的对象复制到Survivor2。幸存者地区被交换。如果一个对象足够大或Survivor2已满,则将其移至Old。最后,当Old接近满时,将调用完整的GC。

答案 3 :(得分:1)

根据弹性分布式数据集文件 -

  

我们的工作节点将内存中的RDD分区缓存为   Java对象。我们使用LRU替换政策   RDD的级别(即,我们不驱逐分区   RDD以便从同一个加载其他分区   RDD)因为大多数操作都是扫描。我们找到了这个   简单的策略,以便在我们所有的用户应用程序中运行良   远。想要更多控制的程序员也可以设置一个   每个RDD的保留优先级作为缓存的参数。