能否递归调用sbatch?sbatch作业脚本内嵌套提交作业是否可行
问题结论
默认集群配置下,你给出的写法没法稳定实现预期的调度效果,就算在部分特殊配置的集群上能跑通,也有很明显的可靠性坑。
核心问题说明
- 计算节点没有作业提交权限
绝大多数Slurm集群默认只开放登录节点的sbatch提交权限,program.sh是被调度到计算节点上运行的,脚本里写的4个恢复作业提交命令会直接报权限错误,根本进不了调度队列。 - 没有执行结果校验
就算你所在的集群特意放开了计算节点的提交权限,当前写法也不会判断./set_checkpoint到底跑没跑成:不管检查点程序是中途崩溃、运行报错、还是没生成完整的可用检查点,后续4个恢复作业都会被直接提交。这些作业启动后找不到有效检查点会直接失败,平白浪费计算资源。 - 补充说明:Shell本身默认是按顺序同步执行命令的,如果
./set_checkpoint是前台运行、没被放到后台,理论上确实会等检查点程序跑完才会执行后面的sbatch命令,这部分逻辑本身没毛病,但解决不了前面两个硬伤。
推荐实现方式
最稳妥的方案是用Slurm原生的作业依赖功能做流水线,完全不用在作业脚本里嵌套提交作业,步骤如下:
- 先把
program.sh精简到只剩检查点生成逻辑:#!/bin/sh ./set_checkpoint - 在登录节点提交检查点生成作业,记下来返回的作业ID,比如提交后返回
Submitted batch job 12345,作业ID就是12345:sbatch -n 1 -t 12:00:00 --mem=16g program.sh - 提交4个配置变体作业的时候,加上
--dependency=afterok:上一步拿到的检查点作业ID参数就行,示例:
这里的sbatch -n 1 -t 12:00:00 --mem=16g --dependency=afterok:12345 cpt_restore_config1.sh sbatch -n 1 -t 12:00:00 --mem=16g --dependency=afterok:12345 cpt_restore_config2.sh sbatch -n 1 -t 12:00:00 --mem=16g --dependency=afterok:12345 cpt_restore_config3.sh sbatch -n 1 -t 12:00:00 --mem=16g --dependency=afterok:12345 cpt_restore_config4.shafterok规则意思是:只有前面的检查点生成作业跑成功(退出码为0),后面的恢复作业才会被调度启动;如果检查点作业跑失败了,后续作业会一直卡在依赖不满足的状态,不会被调度,从根源上避免提交无效作业。
如果你确认集群放开了计算节点的提交权限,也可以给原脚本加上错误校验逻辑降低失败概率,修改后的program.sh示例:
#!/bin/sh set -e # 只要有命令执行失败就直接退出脚本,不继续往下跑 ./set_checkpoint # 额外校验检查点文件是否存在,把ckpt.bin替换成你实际生成的检查点文件名就行 if [ ! -f "./ckpt.bin" ]; then echo "错误:检查点文件未生成,停止提交后续作业" exit 1 fi sbatch -n 1 -t 12:00:00 --mem=16g cpt_restore_config1.sh sbatch -n 1 -t 12:00:00 --mem=16g cpt_restore_config2.sh sbatch -n 1 -t 12:00:00 --mem=16g cpt_restore_config3.sh sbatch -n 1 -t 12:00:00 --mem=16g cpt_restore_config4.sh
内容的提问来源于stack exchange,提问作者Sam Thomas
相关产品推荐
相关产品推荐

