Dask扩展问题:增加工作节点后触发Too many open files错误
解决Dask SSH集群「Too many open files」问题的排查方向
问题背景
通过命令行启动Dask SSH集群:
dask ssh --hostfile $PBS_NODEFILE --nworkers 32 --nthreads 1 &
每个节点配备32核,计算逻辑通过dask_client.map调用mol_dock函数(该函数通过子进程执行命令,读写文件解析结果)。14节点时运行正常,节点数量增加后触发「Too many open files」错误,已调整/etc/security/limits.conf的用户文件打开限制至1000000但无效。
排查与调整方向
1. 确认进程级限制是否实际生效
修改limits.conf后,需确保Dask调度器、Worker进程实际应用了新限制:
- 找到调度器或Worker的PID,执行:
查看cat /proc/<PID>/limitsMax open files的软、硬限制是否为设置的1000000。 - 如果是PBS提交的作业,需在作业脚本中显式添加
ulimit -n 1000000,因为PBS可能不会自动继承系统limits配置,需在作业启动时强制设置。
2. 检查系统级全局文件描述符限制
Linux存在系统全局的文件描述符上限,用户级限制不能超过这个值:
- 查看当前系统全局限制:
sysctl fs.file-max - 查看单个进程允许的最大打开文件数上限:
sysctl fs.nr_open - 如果值过小,修改
/etc/sysctl.conf:
执行fs.file-max = 1000000 fs.nr_open = 1000000sysctl -p使配置生效。
3. 排查mol_dock函数的资源泄漏
mol_dock依赖子进程和文件操作,可能存在未释放的资源:
- 确保子进程正确回收:优先使用
subprocess.run()而非低层级调用,该方法会自动等待子进程结束并释放资源;避免使用subprocess.Popen后未调用wait()或communicate()。 - 显式关闭文件句柄:所有文件操作使用
with open(...) as f:上下文管理器,确保文件自动关闭,避免遗漏。 - 在Worker节点用
lsof -p <Worker-PID>查看进程打开的文件列表,排查是否有大量未关闭的文件、管道或子进程。
4. 调整Dask并发与配置,减少资源占用
节点增多后并发任务数剧增,可通过以下方式降低资源消耗:
- 限制Worker并发任务数:虽然每个节点设32个Worker,但
mol_dock是耗时任务,可通过Dask配置限制每个Worker同时运行的任务数,比如在启动时添加--resources "cpu=1",或修改配置文件设置distributed.worker.concurrency.target = 1。 - 降低系统监控频率:错误由SystemMonitor读取
/proc文件触发,可修改Dask配置增大监控间隔:import dask dask.config.set({"distributed.scheduler.system-monitor.interval": 5}) # 改为5秒 - 优化
as_completed处理逻辑:及时处理结果并释放future,避免持有大量未处理的任务句柄。
5. 检查PBS作业集群的专属限制
部分PBS集群会设置作业级别的资源限制:
- 联系集群管理员确认是否存在作业级的文件描述符上限。
- 在PBS作业脚本开头添加
ulimit -n 1000000,强制为作业进程设置限制。
6. 排查psutil库问题
错误日志显示psutil在读取/proc文件时出错,可尝试:
- 升级psutil到最新版本:
pip install --upgrade psutil - 若不需要系统监控,可在Dask中禁用相关功能,比如设置
distributed.scheduler.system-monitor.enable = false。
内容的提问来源于stack exchange,提问作者DrDom
相关产品推荐
相关产品推荐

