【问题标题】:Unaccountable Dask memory usage无法解释的 Dask 内存使用情况
【发布时间】:2021-07-20 03:30:02
【问题描述】:

我正在深入研究 Dask,并且(大部分)对它感到满意。但是我无法理解以下场景中发生了什么。 TBH,我敢肯定过去有人问过这样的问题,但是在搜索了一段时间后,我似乎找不到真正击中钉子的问题。所以我们来了!

在下面的代码中,你可以看到一个简单的 python 函数,上面有一个 Dask 延迟装饰器。在我的真实用例场景中,这将是一个“黑匣子”类型的函数,我不在乎会发生什么,只要它保持 4 GB 的内存预算并最终返回一个 pandas 数据帧。在这种情况下,我特别选择了值N=1.5e8,因为这会导致总内存占用接近 2.2 GB(很大,但仍然在预算范围内)。最后,当将此文件作为脚本执行时,我有一个“数据管道”,它只是为一些 ID 运行黑盒函数,最后构建一个结果数据框(然后我可以用它做更多的事情)

执行此操作时会出现令人困惑的位。我可以看到一次只执行了两个函数调用(这是我所期望的),但我收到了警告消息distributed.worker - WARNING - Memory use is high but worker has no data to store to disk. Perhaps some other process is leaking memory? Process memory: 3.16 GiB -- Worker memory limit: 3.73 GiB,此后不久脚本过早退出。这个内存使用量来自哪里?请注意,如果我增加 memory_limit="8GB"(这实际上比我的计算机更多),那么脚本运行良好,并且我的打印语句通知我数据帧确实只使用了 2.2 GB 的内存

请帮助我理解这种行为,并希望实施一种更安全的方法

非常感谢!

顺便说一句:

  • 如果有帮助,我使用的是 python 3.8.8、dask 2021.4.0 和分布式 2021.4.0
  • 我还在 Linux (Ubuntu) 机器和 Mac M1 上确认了这种行为。它们都表现出相同的行为,尽管 Mac M1 因相同的原因而失败,并且内存使用量要少得多(N=3e7,或大约 500 MB)

import time

import pandas as pd
import numpy as np
from dask.distributed import LocalCluster, Client
import dask


@dask.delayed
def do_pandas_thing(id):
    print(f"STARTING: {id}")
    N = 1.5e8
    df = pd.DataFrame({"a": np.arange(N), "b": np.arange(N)})

    print(
        f"df memory usage {df.memory_usage().sum()/(2**30):.3f} GB",
    )

    # Simulate a "long" computation
    time.sleep(5)

    return df.iloc[[-1]]  # return the last row


if __name__ == "__main__":
    cluster = LocalCluster(
        n_workers=2,
        memory_limit="4GB",
        threads_per_worker=1,
        processes=True,
    )
    client = Client(cluster)

    # Evaluate "black box" functions with pandas inside
    results = []
    for i in range(10):
        results.append(do_pandas_thing(i))

    # compute
    r = dask.compute(results)[0]

    print(pd.concat(r, ignore_index=True))

【问题讨论】:

    标签: pandas dask dask-distributed


    【解决方案1】:

    我无法使用以下版本重现警告/错误:

    • 熊猫=1.2.4
    • dask=2021.4.1
    • python=3.8.8

    当对象大小增加时,进程确实会因内存而崩溃,但最好让工作负载占可用内存的一小部分:

    简而言之,我们在 2011 年并没有考虑分析 100 GB 或 1 TB 的数据集。如今,我对 pandas 的经验法则是,您的 RAM 应该是数据集大小的 5 到 10 倍.所以如果你有一个 10 GB 的数据集,你应该有大约 64 GB,如果你想避免内存管理问题,最好是 128 GB 的 RAM。对于希望能够分析其计算机 RAM 大小 2 或 3 倍的数据集的用户来说,这让他们感到震惊。

    source

    【讨论】:

    • 嗯,奇怪。我在 Mac M1 上运行它,如果这对你有意义的话。虽然我刚刚在 Linux 机器上尝试过并且遇到了同样的问题(N 值稍大,现在在上面进行了更新)。 Dask 的行为是否因操作系统而异?
    • 我会避免为各种操作留下很少内存的工作负载。您可能会发现这很有用:stackoverflow.com/a/66768499/10693596
    • 嗨@SultanOrazbayev,谢谢你的提示,我完全一样的看法。这就是我最初使用 500 MB 而不是 3.4 GB 进行测试的原因。增加的内存使用只是为了确保您会出现错误:)。尽管如此,即使保持在内存预算范围内是一种很好的做法,我仍然希望能够在需要时使用它,而在我无法使用的情况下
    • 我已将上述内容更新为“更合理”的 2.2 GB,并测试该行为在几台不同的机器上仍然存在。希望你能看到!
    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 2012-06-02
    • 2011-03-09
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多