【问题标题】:Is manually managing memory with .unpersist() a good idea?使用 .unpersist() 手动管理内存是个好主意吗?
【发布时间】:2017-11-16 14:01:13
【问题描述】:

我在这里阅读了很多关于数据帧上的 unpersist() 的问题和答案。到目前为止,我还没有找到这个问题的答案:

在 Spark 中,一旦我完成了一个数据帧,调用 .unpersist() 来手动强制该数据帧从内存中取消持久化是一个好主意,而不是等待 GC(这是一个昂贵的任务)? 在我的情况下,我正在加载许多数据帧,以便我可以执行连接和其他转换。

因此,例如,如果我想加载并加入 3 个数据帧 A、B 和 C: 我加载数据帧 A 和 B,加入这两个以创建 X,然后 .unpersist() B 因为我不再需要它(但我需要 A),并且可以使用内存来加载 C(这很大)。然后我加载 C,并将 C 连接到 X,在 C 上使用 .unpersist(),这样我就有更多内存用于现在将在 X 和 A 上执行的操作。

我知道 GC 最终会对我来说不会持久化,但我也明白 GC 是一项昂贵的任务,应该尽可能避免。重新表述我的问题:这是手动管理内存以优化我的 Spark 作业的合适方法吗?

我的理解(如有错误请指正):

  • 我知道 .unpersist() 是一种非常便宜的操作。
  • 我知道 GC 最终会在我的数据帧上调用 .unpersist()。
  • 我了解 spark 根据最近使用的策略监控缓存和丢弃。但在某些情况下,我不希望删除“上次使用”的 DF,因此我可以在我知道我将 不需要需要的 datafames 上调用.unpersist()将来,这样我就不会丢弃我需要的 DF,并且以后必须重新加载它们。

如果不清楚,请再次重新表述我的问题:这是对 .unpersist() 的适当使用,还是应该让 Spark 和 GC 完成他们的工作?

提前致谢:)

【问题讨论】:

    标签: scala apache-spark garbage-collection spark-dataframe


    【解决方案1】:

    似乎有些误解。虽然使用unpersist 是一种更好地控制存储的有效方法,但它并不能避免垃圾收集。事实上,所有与缓存数据相关的堆上对象都将被留下垃圾收集器。

    因此,虽然操作本身相对便宜,但它触发的事件链可能并不便宜。幸运的是,显式持久化并不比等待自动清理器或 GC 触发清理器更糟糕,因此如果您想清理特定对象,请继续执行。

    要限制不持久的 GC,可能值得看看 OFF_HEAP StorageLevel

    【讨论】:

    • 感谢您快速简洁的回答!我知道它不会避免垃圾收集,但可能会在不需要时推迟它? :)
    • 我认为最大的优点是它可以让您控制何时释放内存。因此,您可以在迭代之间触发它,例如,而不是在繁重的处理过程中或某些 IO 准备超时。
    猜你喜欢
    • 2016-08-05
    • 1970-01-01
    • 2019-06-23
    • 2013-04-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多