与this question类似,我在分布式Dask时遇到内存问题。然而,在我的例子中,解释并不是客户试图收集大量数据。在
这个问题可以基于一个非常简单的任务图来说明:一个delayed
操作的列表会生成一些固定大小约500MB的随机数据帧(以模拟从文件加载多个分区)。任务图中的下一个操作是获取每个数据帧的大小。最后,所有大小都被缩减为一个总大小,即必须返回给客户端的数据很小。在
出于测试目的,我运行的是一个本地调度器/工作线程,内存限制为2GB,即:
$ dask-scheduler
$ dask-worker localhost:8786 --nthreads 1 --memory-limit 2000000000
我对任务图的期望是,工人永远不需要超过500 MB的RAM,因为在“generate data”之后直接运行“get data size”,会使数据立即变小。然而,我注意到,工人需要的内存远不止这些:
因子2表示数据必须在内部复制。因此,任何使分区大小接近节点物理内存的尝试都会导致MemoryErrors
或大量交换。在
任何能说明这一点的信息都非常感谢。特别是:
memory-limit
如何影响这种行为?从我的测试来看,使用较低的阈值似乎会更早地触发GC(和/或溢出到磁盘?)但另一方面,还有其他内存峰值甚至超过了使用更高阈值的峰值内存。在请注意,我知道我可以通过在第一次操作中使用的大小来解决这个问题,而且Dask的单机执行器可能更适合这个问题,但我是出于教育目的而要求的。在
附件1:测试代码
^{pr2}$附件2:DAG图解
这里有几个问题:
为什么我的内存使用量是原来的两倍?
在到达第一个compute size任务之前,worker可能正在运行两个create data任务。这是因为调度程序将所有当前可运行的任务分配给工作线程,可能比它们一次可以运行的任务还多。工作线程完成第一个任务并向调度程序报告。当调度程序确定要发送给worker的新任务(compute size任务)时,worker立即启动另一个create data任务。在
建议的行为是使分区大小远低于总内存吗?
是的。在
当扩展超出内存限制值时会发生什么?
工作线程将开始将最近最少使用的数据元素写入磁盘。默认情况下,当内存使用率达到60%时(按照
__sizeof__
协议来衡量),它就会这样做。在注意:感谢您提出的问题
相关问题 更多 >
编程相关推荐