Dask计算随时间推移逐渐变慢问题求助
解决Dask计算任务随时间逐渐变慢的问题
从你描述的现象和警告信息来看,核心问题大概率是内存泄漏引发的频繁Full GC——Full GC会占用大量CPU资源,导致Worker无法专注于计算任务,最终表现为CPU使用率下降、任务耗时增加。下面结合你的场景给出具体的排查思路和解决方案:
一、最可能的根源:未关闭的h5py文件句柄
看你的process函数,每次打开h5py.File后都没有关闭它!这会导致大量文件句柄和相关内存资源无法释放,随着迭代次数增加,内存占用持续上升,触发频繁的Full GC(这和你看到的distributed.utils_perf警告完全对应)。
修复方法
修改process函数,用with语句自动管理文件句柄,确保每次计算完成后文件被正确关闭:
def process(path): # 用with语句包裹h5py.File,自动关闭文件 with h5py.File(path) as f: d = f['/x'] darr = da.from_array(d, chunks=d.chunks) mapped = darr.map_blocks(np.fft.fft) absolute = da.absolute(mapped) reduced = absolute.mean(axis=-1) return reduced.compute()
二、升级Dask及依赖版本
你使用的Dask版本是2021.4.0,这个版本比较老旧,后续版本修复了不少内存泄漏和分布式调度的性能问题,尤其是distributed组件中关于垃圾回收和Worker资源管理的bug。
操作步骤
在容器内执行升级命令:
pip install --upgrade dask distributed numpy h5py bokeh
升级后重启调度器和Worker,再测试任务耗时变化。
三、优化Dask的垃圾回收配置
如果内存泄漏问题得到缓解但仍有GC占用过高的情况,可以调整Dask的GC策略:
- 在启动Client后,设置Worker的内存目标阈值,让GC在内存占用达到一定比例时再触发(默认值可能偏低):
from dask.distributed import Client c = Client() # 设置内存使用到80%时开始触发GC,减少GC频率 c.worker.memory.target = 0.8 c.worker.memory.spill = 0.85 # 内存到85%时开始溢出到磁盘
- 如果不需要Dask dashboard,可以关闭它避免协程泄漏(对应你看到的Bokeh警告):
c = Client(dashboard_address=None)
四、验证修复效果
修改代码并升级依赖后,重新运行你的基准测试:
- 观察Worker的CPU使用率是否能稳定维持在较高水平
- 查看
benchmark.csv的耗时是否不再持续上涨 - 停止调度器后,是否还会出现大量Full GC警告
额外排查点
如果以上方法仍未解决问题,可以通过Dask dashboard进一步定位:
- 查看Memory标签页,观察Worker的内存是否持续上涨(如果是,说明还有其他内存泄漏点)
- 查看Tasks标签页,观察任务的等待时间是否异常增加(可能是调度器资源不足)
内容的提问来源于stack exchange,提问作者rafgonsi




