dask read_拼花地板内存不足

dask read_拼花地板内存不足,dask,Dask,我试图读取一个大的(不适合内存)拼花地板数据集,然后从中提取样本。数据集的每个分区都完全适合内存 数据集是磁盘上大约20Gb的数据,分为104个分区,每个分区大约200Mb。我不想在任何时候使用超过40Gb的内存,因此我正在相应地设置n\u workers和memory\u limit 我的假设是Dask将加载尽可能多的分区,从中采样,从内存中删除分区,然后继续加载下一个分区。或者类似的 相反,从执行图(104个并行加载操作,在每个示例之后)判断,它似乎试图同时加载所有分区,因此工作进程总是因为

我试图读取一个大的(不适合内存)拼花地板数据集,然后从中提取样本。数据集的每个分区都完全适合内存

数据集是磁盘上大约20Gb的数据,分为104个分区,每个分区大约200Mb。我不想在任何时候使用超过40Gb的内存,因此我正在相应地设置
n\u workers
memory\u limit

我的假设是Dask将加载尽可能多的分区,从中采样,从内存中删除分区,然后继续加载下一个分区。或者类似的

相反,从执行图(104个并行加载操作,在每个示例之后)判断,它似乎试图同时加载所有分区,因此工作进程总是因为内存不足而被杀死

我错过什么了吗

这是我的代码:

从日期时间导入日期时间
从dask.distributed导入客户端
客户机=客户机(n_工作者=4,内存限制=10e9)#每个工作者Gb
将dask.dataframe作为dd导入
df=dd.read_拼花地板(“/path/to/dataset/”)
df=样品df(分数=0.01)
df=df.compute()
要再现错误,您可以创建一个模拟数据集,其大小为我使用此代码尝试加载的数据集的十分之一,并使用1GB
内存限制=1e9
尝试我的代码进行补偿

来自dask.distributed import客户端
client=client()#根据您的系统在此处添加限制
从dask导入数据集
df=数据集.时间序列(end='2002-12-31')
df=df.重新分区(npartitions=104)
df.to_拼花地板('./模拟_数据集')

拼花地板是一种高效的二进制格式,具有编码和压缩功能。很有可能在记忆中,它占据的空间比你想象的要大得多

为了以1%的采样率对数据进行采样,在选择子分区之前,要将每个分区全部加载并扩展到内存中。这带来了相当大的缓冲区拷贝内存开销。每个工作线程将需要容纳当前处理的块,以及迄今为止在该工作线程上累积的结果,然后一个任务将为最终的concat操作复制所有这些结果(这也涉及复制和开销)


一般建议是,每个工作区都应该能够访问每个分区的内存大小的“几倍”,在您的情况下,这些分区的磁盘大小为2GB,内存更大。

拼花是一种高效的二进制格式,具有编码和压缩功能。很有可能在记忆中,它占据的空间比你想象的要大得多

为了以1%的采样率对数据进行采样,在选择子分区之前,要将每个分区全部加载并扩展到内存中。这带来了相当大的缓冲区拷贝内存开销。每个工作线程将需要容纳当前处理的块,以及迄今为止在该工作线程上累积的结果,然后一个任务将为最终的concat操作复制所有这些结果(这也涉及复制和开销)


一般建议是,每个工作区都应该能够访问每个分区内存大小的“几倍”,在您的情况下,这些分区的磁盘内存大小为2GB左右,内存更大。

Hi Eduardo,您的机器中有多少ram?我试图用一台16 GB的机器重现你的问题,我分配了4个工人,每个工人有3 GB的RAM,你的代码工作得很好。这是磁盘上的200 GB吗?@rpanai这是一台有数百个RAM的服务器,但我不是唯一使用它的人。这就是为什么我提到我假设我有40Gb(我肯定有更多,但应该足够了)。您加载的数据集有多大?@mdurant是的,磁盘上有200GB。我将编辑这篇文章以使其更清晰。@rpanai我在描述中添加了生成模拟数据集的代码嗨,爱德华多,你的机器有多少内存?我试图用一台16 GB的机器重现你的问题,我分配了4个工人,每个工人有3 GB的RAM,你的代码工作得很好。这是磁盘上的200 GB吗?@rpanai这是一台有数百个RAM的服务器,但我不是唯一使用它的人。这就是为什么我提到我假设我有40Gb(我肯定有更多,但应该足够了)。您加载的数据集有多大?@mdurant是的,磁盘上有200GB。我将编辑这篇文章以使其更清晰。@rpanai我在描述中添加了生成模拟数据集的代码。对不起,200Gb是打字错误,实际数字是20Gb。分区大小是正确的,它是200Mb,工作区有10Gb的限制,这应该不是问题。此外,如果我将一个worker设置为10Gb,只加载一个分区(而不是整个数据集),它可以很好地加载,因此每个分区都必须适合内存。因此,我建议您衡量加载、采样和将内存存储在数据中的效果,这里的数字将是关键。很抱歉,200Gb是一个输入错误,实际数字是20Gb。分区大小是正确的,它是200Mb,工作区有10Gb的限制,这应该不是问题。此外,如果我将一个worker设置为10Gb,只加载一个分区(而不是整个数据集),它可以很好地加载,因此每个分区都必须适合内存。因此,我建议您衡量加载、采样和将内存存储在数据中的效果,这里的数字将是关键。