Kedro 0.17.2内存溢出问题:是否存在DataFrame内存重复及如何规避
Kedro 内存重复占用问题解决方案
核心问题原因
你观察到的内存重复占用确实和Kedro的默认机制有关,额外运行的子进程为memory-profiler的mprof工具自带的监控进程,和Kedro运行逻辑无关。
默认配置下,Kedro的DataCatalog对内存型数据集(MemoryDataSet)默认使用深拷贝模式存储,同时会缓存所有已加载的数据集直到整个Pipeline运行完成,不会主动释放中间节点的输出/输入数据,这就会导致运行过程中内存里同时存在多份相同DataFrame的拷贝,占用双倍甚至多倍内存。
可行的优化方案
- 调整内存数据集的拷贝模式
在conf/base/catalog.yml中给所有内存存储的DataFrame数据集添加copy_mode配置,避免深拷贝生成重复数据:你的数据集名称: type: MemoryDataSet copy_mode: assignassign模式会直接传递DataFrame的引用,不会额外生成拷贝,可直接降低一半左右的内存占用。 - 配置运行后自动释放内存的钩子
新增自定义Hook在每个节点运行完成后主动释放后续不再使用的中间数据集,步骤如下:- 在项目的
src/<你的项目名>/hooks.py中添加如下代码:
from kedro.framework.hooks import hook_impl from kedro.io import DataCatalog from kedro.extras.datasets.pandas import MemoryDataSet class MemoryReleaseHook: @hook_impl def on_node_complete(self, node, catalog: DataCatalog, inputs, outputs): # 释放当前节点已使用完成的输入数据集 for input_ds in node.inputs: if catalog.exists(input_ds) and isinstance(catalog._data_sets[input_ds], MemoryDataSet): catalog.release(input_ds)- 在
src/<你的项目名>/settings.py中注册该Hook:
HOOKS = (MemoryReleaseHook(),) - 在项目的
- 避免手动全量加载数据集
不要在节点代码外手动调用catalog.load()加载大量数据集,所有数据读取逻辑交由Kedro基于节点依赖自动处理,加载后的数据集会自动遵循上述的释放规则。
内容的提问来源于stack exchange,提问作者lspinheiro
相关产品推荐
相关产品推荐

