Dask worker卡SLURM队列未启动master即达墙钟时间如何解决
Dask+SLURM环境问题解决方案
方案1:强制master等待worker就绪后再执行业务逻辑
- 第一种方式:将scheduler(master)和所有worker放在同一个SLURM作业中提交,避免分开提交产生的调度优先级差、资源分配不同步问题。示例sbatch脚本如下:
#!/bin/bash #SBATCH --job-name=dask_ml_task #SBATCH --nodes=4 # 总共申请4个节点,1个跑scheduler 3个跑worker #SBATCH --time=24:00:00 #SBATCH --partition=你的集群分区名 # 启动scheduler,将连接信息写入共享存储的配置文件 dask scheduler --scheduler-file /共享目录路径/dask-scheduler.json & SCHEDULER_PID=$! # 等待scheduler启动完成 sleep 10 # 在所有申请到的节点上同时启动worker,指向同一个scheduler配置文件 srun dask worker --scheduler-file /共享目录路径/dask-scheduler.json --nworkers 1 --nthreads 16 --memory-limit 64GB & # 等待所有worker连接后再启动业务代码 python 你的机器学习代码路径.py # 业务逻辑跑完后终止scheduler进程 kill $SCHEDULER_PID
该方式下所有资源由SLURM一次性分配,不会出现scheduler已经运行、worker还在排队的问题。
- 第二种方式:如果必须分开提交scheduler和worker作业,在scheduler侧的业务代码中调用
wait_for_workers方法阻塞,直到指定数量的worker就绪再运行计算逻辑:
from dask_jobqueue import SLURMCluster from dask.distributed import Client cluster = SLURMCluster( cores=16, memory="64GB", queue="你的集群分区名", walltime="24:00:00" ) # 申请3个worker资源 cluster.scale(3) client = Client(cluster) # 阻塞直到3个worker全部连接成功,再执行后续业务逻辑 client.wait_for_workers(3) # 后续机器学习计算逻辑
方案2:新master承接已运行的worker
核心逻辑是持久化scheduler连接信息,允许worker在scheduler重启后重新关联:
- 首次启动scheduler时添加参数
--scheduler-file /共享目录路径/dask-scheduler.json,将连接信息写入所有节点可访问的共享存储路径 - 启动worker时添加两个参数:
--scheduler-file /共享目录路径/dask-scheduler.json指向同一个配置文件,--death-timeout 86400设置scheduler断连后worker最多等待24小时再退出,预留足够的master重启时间 - 原master进程退出后,重启新master时直接加载同一个scheduler文件即可自动连接所有存活的worker:
from dask.distributed import Client client = Client(scheduler_file="/共享目录路径/dask-scheduler.json")
24小时墙钟限制适配优化
- 对计算任务设置检查点,将中间结果写入共享存储,单次作业运行达到时长上限前保存状态,下次重启作业直接读取中间结果继续计算
- 拆分长任务为多个执行时长小于24小时的子任务,通过SLURM的
--dependency参数设置作业依赖,前序子任务跑完自动启动后序子任务 - 调整作业提交参数,同一批任务使用同一个SLURM账户/分区提交,避免资源优先级不足导致排队时间过长
内容的提问来源于stack exchange,提问作者Marta Moreno
相关产品推荐
相关产品推荐

