用户需求

已经提交了很多任务,一部分已经在计算中 RUN,一部分在排队中 PD。现在新提交一个任务,希望该任务能够优先计算。

解决思路

使用 yhcontrol hold | release 来解决。

解决步骤

  1. 提交新任务。
  2. 使用yhcontrol hold暂停 已经提交任务中状态为排队 PD 的任务。
  3. 等待新任务开始计算,使用yhcontrol release来 恢复之前被 暂停 的任务。(手动或写脚本自动实现)

举例说明

1.提交新任务

已经提交了5个任务,使用 yhq 命令查看,得到如下结果:

$ yhq
JOBID     PARTITION  NAME     USER       ST  TIME      NODES NODELIST(REASON)
100001    debug      sub.sh   zhenggang  R   00:05:01  1     cn[11]
100002    debug      sub.sh   zhenggang  R   00:05:02  1     cn[12]
100003    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100004    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100005    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)

其中,100001 100002 在计算, 100003 100004 100005 在排队。

现在我们提交一个新的任务,然后再 yhq 查看,得到如下结果:

$ yhq
JOBID     PARTITION  NAME     USER       ST  TIME      NODES NODELIST(REASON)
100001    debug      sub.sh   zhenggang  R   00:05:11  1     cn[11]
100002    debug      sub.sh   zhenggang  R   00:05:12  1     cn[12]
100003    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100004    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100005    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100006    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)

2.暂停任务

我们希望任务 100006 在任务 100003 100004 100005 之前先计算,那么我们就将这3个任务 hold 一下:

yhcontrol hold 100003 100004 100005

然后我们再 yhq 查看,得到如下结果:

$ yhq
JOBID     PARTITION  NAME     USER       ST  TIME      NODES NODELIST(REASON)
100001    debug      sub.sh   zhenggang  R   00:05:21  1     cn[11]
100002    debug      sub.sh   zhenggang  R   00:05:22  1     cn[12]
100003    debug      sub.sh   zhenggang  PD  0:00      1     (JobHeldUser)
100004    debug      sub.sh   zhenggang  PD  0:00      1     (JobHeldUser)
100005    debug      sub.sh   zhenggang  PD  0:00      1     (JobHeldUser)
100006    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)

可以看到这3个任务的 NODELIST(REASON) 变为了 JobHeldUser

这样修改后,当系统有可用的计算资源时,会优先计算任务 100006 ,跳过被 hold 的任务。

3.恢复任务

之前我们把任务 100003 100004 100005 变为了 hold 的任务,如果不恢复,那么它们会一直无法计算的。

所以需要在希望优先计算的任务 100006 开始计算后,将这些被 hold 的任务状态改回来,即为 release , 命令如下:

yhcontrol release 100003 100004 100005

然后我们再 yhq 查看,得到如下结果:

$ yhq
JOBID     PARTITION  NAME     USER       ST  TIME      NODES NODELIST(REASON)
100001    debug      sub.sh   zhenggang  R   00:05:21  1     cn[11]
100002    debug      sub.sh   zhenggang  R   00:05:22  1     cn[12]
100003    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100004    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100005    debug      sub.sh   zhenggang  PD  0:00      1     (Resources)
100006    debug      sub.sh   zhenggang  R   0:10      1     cn[13]

4.自动暂停|恢复

4.1 暂停任务

当需要被 hold 的任务很多的时候,使用 yhq 命令得到 jobid 的列表,然后逐一粘贴,不是很方便。我们可以写一个简单的脚本实现。

1.获得需要被hold的任务列表,存到一个临时文件 jobhold.txt 中:

yhq | grep PD | awk '{print $1}' > jobhold.txt

2.循环遍历这个临时文件的每一行,逐一 hold 这些任务:

for jobid in `cat jobhold.txt`;
do
yhcontrol hold $jobid
done

4.2 恢复任务

我们可以编写一个脚本,例如 jobrelease.sh ,然后提交到登陆节点后台,自动的定期检查新提交任务的状态,如果任务已经在计算,则自动恢复之前被 hold 的任务。脚本举例如下:

#!/bin/bash

jobid=100006

while ture
do
  jobst=`yhqueue | grep $jobid | awk '{print $5}' || echo "None"`
  if [[ $jobst == 'PD' ]];then
    sleep 60
  else
    for jobid in `cat jobhold.txt`;
    do
      yhcontrol release $jobid
    done
    break
  fi
done

脚本中 jobid='100006' 需要根据实际需求来修改。

然后将这个脚本提交到登陆节点后台:

chmod +x jobrelease.sh
nohup ./jobrelease.sh > /dev/null 2>&1 &

如果我们不止有一个任务需要被优先计算,例如新提交了 100006 100007 100008 三个任务,希望先算这3个,然后再算之前提交的任务,我们可以略微修改一下刚才的 jobrelease.sh 脚本:

#!/bin/bash

jobids=(100006 100007 100008)
bool_release=true

while true;
do
  for jobid in ${jobids[@]}
  do
    jobst=`yhqueue | grep $jobid | awk '{print $5}' || echo "None"`
    if [[ $jobst == 'PD' ]] ;then
      bool_release=false
    fi
  done
  
  if [[ $bool_release == 'true' ]] ;then 
    for jobid in `cat jobhold.txt`;
    do
      yhcontrol release $jobid
    done
    break
  else
    sleep 60
  fi
done

然后再提交:

chmod +x jobrelease.sh
nohup ./jobrelease.sh > /dev/null 2>&1 &