我有一个大数据问题。特定的问题不是很重要,但是我已经用dask解决了。现在我有两个问题。
from dask import distributed
import numpy as np
local_cluster = distributed.LocalCluster(n_workers=20, processes=True, memory_limit=0)
dask_client = distributed.Client(local_cluster)
hat_matrix = np.random.rand(1000,25000)
weight_matrix = np.random.rand(1000)
Y = np.random.rand(1000, 25000)
[scatter_hat] = dask_client.scatter([hat_matrix], broadcast=True)
[scatter_weight] = dask_client.scatter([weight_matrix], broadcast=True)
futures = [dask_client.submit(apply_function, i, scatter_hat, Y[i, :], scatter_weight)
for i in range(Y.shape[0])]
results = dask_client.gather(futures)
我可以拆分Y
(这很好,因为我没有足够的内存来一次真正加载所有内存),但是我的所有工作人员都需要hat_matrix
。分散hat_matrix
,然后按行发送Y
效果很好。除了hat_matrix
和Y
都很大以外,还可以。我准备了足够的内存来处理它。但是我找不到任何办法允许短的内存峰值(在反序列化期间发生),因此,如果我设置了内存限制,保姆会杀死我的所有工作人员。然后是我所有的新工人。等等等等。所以我有三个问题:
是否有一种方法来设置内存限制,以允许在序列化数据进入和解压缩时出现峰值?如果我有64 GB的内存来驱动20个进程,那么我想将每个进程的内存限制设置为2.8GB。当我分散2GB的数据时,每个进程进行反序列化的峰值都会达到〜4GB,而保姆会杀死所有内容。
有没有一种方法可以分散散射以最大程度地减少瞬态记忆峰值?
是否有一种方便的方法通过磁盘而不是通过TCP分散数据,还是必须自定义写入? (作为一个必然结果:是否有一种方便的方法可以从我所有工作程序中的序列化文件中加载内存映射的dask阵列?)
答案 0 :(得分:1)
是否有一种方法来设置内存限制,以允许在序列化数据进入和解压缩时出现峰值?
通常,反序列化运行任意代码,因此dask无法真正控制发生的事情。实际上,尽管与现代硬件上可用的典型内存相比,您的矩阵实际上并没有那么大,但是令您惊讶的是,您遇到了一个问题。 Dask对NumPy数组非常谨慎。我不希望它使用比数组大小更多的内存。
有没有一种方法可以分散散射以最大程度地减少瞬态记忆峰值?
散射目前通过广播树。您的客户将派遣给一些工作人员,然后再派遣给更多工作人员,依此类推。默认情况下,这里的分支因子只有两个,所以如果在这里看到巨大的爆炸,我会感到惊讶。
是否有一种方便的方法通过磁盘而不是通过TCP分散数据,还是必须自定义写入? (作为一个必然结果:是否有一种方便的方法可以从我所有工作程序中的序列化文件中加载内存映射的dask阵列?)
也许您可以使用某种内存映射的NumPy数组而不是内存中的NumPy数组?