Back To Basis : Torque & MAUI
Rapide tip pour sauver ce qui me reste de mémoire avec la mise en place et l'exploitation d'un cluster de calcul via Torque et MAUI.
Fonctionnement
Un cluster de calcul est composé de noeuds de calcul, plus ou moins riches en ressources, et à plus ou moins charger. Typiquement, ici, j'ai un cluster composé de 2 ensembles :- les noeuds de calcul 24/24 7/7
- les noeuds de calcul cumulant 2 rôles et qui sont principalement des postes de travail
Ces contraintes sont notamment liées au temps d'exécution qui est borné, et selon votre bon plaisir, le mien en tout cas, à un maximum de soumission et de jobs en cours d'exécution.
Comment faire ? Il suffit de continuer à lire :)
Configuration
Maui
En réalité, MAUI n'a pas besoin, sauf cas particulier -du genre allouer telle ressources entre telle heure et telle heure à tel utilisateur- de configuration spécifique. Tout ce qu'il y a à savoir se trouve sous /var/spool/maui/maui.cfg, je vous ai même rajouté ce cas particulier dont je vous parlais :$ cat /var/spool/maui/maui.cfg | grep -v "#" SERVERHOST master ADMIN1 root RMCFG[base] TYPE=PBS AMCFG[bank] TYPE=NONE RMPOLLINTERVAL 00:00:30 SERVERPORT 50001 SERVERMODE NORMAL LOGDIR /var/log/maui LOGFILE maui.log LOGFILEMAXSIZE 1000000000 LOGLEVEL 3 QUEUETIMEWEIGHT 1 BACKFILLPOLICY FIRSTFIT RESERVATIONPOLICY CURRENTHIGHEST NODEALLOCATIONPOLICY LASTAVAILABLE SRCFG[prioritaire] PERIOD=DAY SRCFG[prioritaire] STARTTIME=3:00:00 SRCFG[prioritaire] ENDTIME=11:45:00 SRCFG[prioritaire] HOSTLIST=ktux-w1,ktux-w2 SRCFG[prioritaire] USERLIST=kuser
Torque
Par défaut, l'installation de Torque / PBS vous a crée un petit fichier de conf, destiné à paramétrer notamment le démarrage des services. Il nous indique également où est le home de Torque, c'est-à-dire où il range ses petites affaires. Ici, c'est sous /var/spool/pbs.$ cat /etc/pbs.conf #!/bin/sh # init of some var needed bi pbs service # config: /etc/pbs.conf pbs_home=/var/spool/pbs pbs_exec=/usr # set 1 to start the service start_server=1 start_sched=0 start_mom=0
/var/spool/pbs
Ce répertoire contient notamment les logs, mais aussi les données relatives aux queues et aux jobs$ ll /var/spool/pbs/ total 112 drwxr-xr-x 2 root root 4096 2011-06-06 02:40 aux/ drwx------ 2 root root 4096 2011-06-06 02:40 checkpoint/ drwxr-xr-x 2 root root 4096 2011-06-06 00:00 mom_logs/ drwxr-xr-x 3 root root 4096 2011-06-06 09:20 mom_priv/ -rw-r--r-- 1 root root 56261 2011-06-06 12:46 nodes -rwxr-xr-x 1 root root 2317 2011-06-06 02:41 pbs_config.sample* -rw-r--r-- 1 root root 26 2011-06-06 02:40 pbs_environment drwxr-xr-x 2 root root 4096 2011-06-06 09:40 sched_logs/ drwxr-xr-x 3 root root 4096 2011-06-06 10:33 sched_priv/ drwxr-xr-x 2 root root 4096 2011-06-06 00:00 server_logs/ -rwxr-xr-x 1 root root 13 2011-06-06 16:39 server_name* drwxr-xr-x 12 root root 4096 2011-06-06 15:10 server_priv/ drwxrwxrwt 2 root pbs 4096 2011-06-06 12:30 spool/ drwxrwxrwt 2 root pbs 4096 2011-06-06 02:40 undelivered/Principalement, ce qui nous intéressera sera situé sous server_priv :
$ ll /var/spool/pbs/server_priv/ total 328 drwxr-xr-x 2 root root 12288 2011-06-06 05:00 accounting/ drwxr-xr-x 2 root root 4096 2011-06-06 02:40 acl_groups/ drwxr-xr-x 2 root root 4096 2011-06-06 02:40 acl_hosts/ drwxr-xr-x 2 root root 4096 2011-06-06 10:40 acl_svr/ drwxr-xr-x 2 root root 4096 2011-06-06 10:23 acl_users/ drwxr-xr-x 2 root root 4096 2011-06-06 02:40 arrays/ drwxr-xr-x 2 root root 4096 2011-06-06 02:40 disallowed_types/ drwxr-xr-x 2 root root 4096 2011-06-06 02:40 hostlist/ drwxr-xr-x 2 root root 274432 2011-06-06 10:52 jobs/ -rw-r--r-- 1 root root 1058 2011-06-06 15:10 nodes drwxr-xr-x 2 root root 4096 2011-06-06 06:55 queues/ -rw------- 1 root root 1351 2011-06-06 10:52 serverdb -rw------- 1 root root 5 2011-06-06 09:41 server.lock -rw------- 1 root root 0 2011-06-06 16:47 tracking $ ll /var/spool/pbs/server_priv/queues/ total 36 -rw------- 1 root root 1319 2011-06-06 13:58 longday -rw------- 1 root root 1321 2011-06-06 06:55 longnight -rw------- 1 root root 1320 2011-06-06 13:58 shortday -rw------- 1 root root 1321 2011-06-06 06:55 shortnight $ file /var/spool/pbs/server_priv/queues/shortday /var/spool/pbs/server_priv/queues/shortday: dataEt sous server_logs :
$ ll /var/spool/pbs/server_logs/ | head -rw-r--r-- 1 root root 315447768 2011-06-06 00:00 20110606Tout ça pour dire que c'est facile de retrouver une information.
Queues
Je vous parlais plus haut de queue. Une queue est exactement ce à quoi son nom fait penser : c'est une file type FIFO qui contient les travaux en attente. L'utilitaire par définition qui va s'occuper de créer et moduler nos queues comme bon nous semble répond au doux nom de qmgr. Ce qui est bien avec lui, c'est qu'il permet, juste en lançant une petite requête, de nous dumper l'essentiel des commandes nécessaires à créer et paramétrer les queues que nous nous sommes donné tant de mal à créer. Ca me permet de faire 2 manips en une : une, vous montrer comment interroger Torque, et deux, vous montrer comment créer une queue :)$ qmgr -c "print queue @master" # # Create queues and set their attributes. # # # Create and define queue longday # create queue longday set queue longday queue_type = Execution set queue longday Priority = 4 set queue longday max_user_queuable = 30 set queue longday from_route_only = False set queue longday resources_default.neednodes = day set queue longday resources_default.nodect = 1 set queue longday resources_default.nodes = 1:day set queue longday resources_default.walltime = 100:00:00 set queue longday max_user_run = 6 set queue longday enabled = True set queue longday started = True # # Create and define queue shortday # create queue shortday set queue shortday queue_type = Execution set queue shortday Priority = 2 set queue shortday max_user_queuable = 200 set queue shortday from_route_only = False set queue shortday resources_max.walltime = 03:00:00 set queue shortday resources_default.neednodes = day set queue shortday resources_default.nodect = 1 set queue shortday resources_default.nodes = 1:day set queue shortday resources_default.walltime = 03:00:00 set queue shortday max_user_run = 12 set queue shortday enabled = True set queue shortday started = True # # Create and define queue shortnight # create queue shortnight set queue shortnight queue_type = Execution set queue shortnight Priority = 2 set queue shortnight max_user_queuable = 400 set queue shortnight from_route_only = False set queue shortnight resources_max.walltime = 04:00:00 set queue shortnight resources_default.neednodes = night set queue shortnight resources_default.nodect = 1 set queue shortnight resources_default.nodes = 1:night set queue shortnight resources_default.walltime = 04:00:00 set queue shortnight max_user_run = 70 set queue shortnight enabled = True set queue shortnight started = False # # Create and define queue longnight # create queue longnight set queue longnight queue_type = Execution set queue longnight Priority = 4 set queue longnight max_user_queuable = 180 set queue longnight from_route_only = False set queue longnight resources_default.neednodes = night set queue longnight resources_default.nodect = 1 set queue longnight resources_default.nodes = 1:night set queue longnight resources_default.walltime = 100:00:00 set queue longnight max_user_run = 30 set queue longnight enabled = True set queue longnight started = FalseComme vous pouvez le voir, les priorités entre queues sont tranchées au couteau : les queues de priorité moindre seront plus prioritaire que celles ayant une valeur plus grandes. Pour modifier un de ces paramètres, il suffit de les modifier avec par exemple un :
$ qmgr -c "set queue longnight max_user_run = 20"
Noeuds de calcul
Pour rajouter des noeuds de calcul, il faut être un peu plus sournois : il faut jouer avec les propriétés du noeud. Même principe, je print, mais pour le créer, soit on passe par un qmgr -c, soit qmgr tout court, qui nous renvoie un prompt :$ qmgr -c "print node ktux-1" # # Create and define node ktux-1 # create node ktux-1 set node ktux-1 np = 2 set node ktux-1 properties = night set node ktux-1 ntype = clusterIci, je dis que mon noeud ktux-1 a 2 CPUs, de type cluster et doit faire jouer uniquement les travaux en mode night. Pour un noeud de calcul 24/24, 7/7, ça donnera plus du genre : Via qmgr -c :
$ qmgr -c 'create node ktux-w1 np=4,ntype=cluster' $ qmgr -c 'set node ktux-w1 properties=day'Ce qui nous donne :
$ qmgr -c "print node ktux-w1" # # Create nodes and set their properties. # # # Create and define node ktux-w1 # create node ktux-w1 set node ktux-w1 state = free set node ktux-w1 np = 4 set node ktux-w1 properties = day set node ktux-w1 ntype = clusterAu fur et à mesure que les noeuds communiqueront avec le master, tout un tas d'autres infos vont être remontées, comme l'état actuel, les jobs en cours sur ce noeud, ...
$ qmgr -c "print node ktux-w1" # # Create nodes and set their properties. # # # Create and define node ktux-w1 # create node ktux-w1 set node ktux-w1 state = busy set node ktux-w1 np = 4 set node ktux-w1 properties = day set node ktux-w1 ntype = cluster set node ktux-w1 status = opsys=linux set node ktux-w1 status += uname=Linux ktux-w1 2.6.31.14-server-1mnb set node ktux-w1 status += sessions=23566 23591 23629 23680 set node ktux-w1 status += nsessions=4 set node ktux-w1status += nusers=1 set node ktux-w1 status += idletime=8968185 set node ktux-w1 status += totmem=9009420kb set node ktux-w1 status += availmem=8458932kb set node ktux-w1 status += physmem=8143220kb set node ktux-w1 status += ncpus=4 set node ktux-w1 status += loadave=1.36 set node ktux-w1 status += netload=2067207052 set node ktux-w1 status += state=free set node ktux-w1 status += jobs=65605 65606 65607 65608 set node ktux-w1 status += varattr= set node ktux-w1 status += rectime=1307353529En réalité, le lien entre properties et queue est fait via l'instruction resources_default.neednodes :
set queue longnight resources_default.neednodes = nightet qmgr mentionne explicitement, pour chaque noeud, à quelle queue il se rattache. Le tout est sous /var/spool/pbs/server_priv/nodes :
$ cat /var/spool/pbs/server_priv/nodes ktux-1 np=2 night ktux-2 np=2 night ktux-3 np=2 night ktux-w1 np=4 day ktux-w2 np=4 daySans ces instructions, on aurait une erreur du genre :
$ qmgr -c "print node ktux-2" qmgr obj=ktux-2 svr=default: Unknown node MSG=cannot located specified node
Évidemment, toute modification doit être ponctuée par un restart de pbs_server pour être effective.
Job
Toute soumission de travail passe par un qsub et doit mentionner le job à faire, la queue sur laquelle on désire travailler et optionnellement si l'on souhaite être averti en allocation des ressources, run et fin du travail. En retour, on obtient un identifiant de travail.$ qsub -q shortday -o /home/kuser/date.res -e /home/kuser/date.err -m abe -N date -M ktux@ktux.com /home/kuser/date.shIci, -q attend une queue spécifique, -o précède l'emplacement de l'output désiré, -e celui de l'erreur renvoyée si il y a, -m abe désigne l'instruction de mailing en cas de a(borted) b(egin) e(nd). -N donne un nom au travail, -M précise le mail en question et en dernier, le script à exécuter. A noter qu'ici, le /home de kuser est un partage NFS, qui fonctionnera quelque soit le noeud de calcul choisi. Autrement, il aurait fallu désigner un espace accessible avec les droits de kuser par le noeud de calcul en question. Sur le master, on peut alors suivre le job et son évolution :
$ qstat -u kuser master : Req'd Req'd Elap Job ID Username Queue Jobname SessID NDS TSK Memory Time S Time -------------------- -------- -------- ---------------- ------ ----- --- ------ ----- - ----- 656969 kuser shortday date -- 1 -- -- 00:45 Q --Q : le job est enqueue. R : running. Sur le client aussi, et ce en étant loggé en tant que kuser :
$ qstat Job id Name User Time Use S Queue ------------------------- ---------------- --------------- -------- - ----- 656969 date kuser 0 Q shortdayUn affichage plus complet passe par un qstat -f, d'où on extrait facilement l'exec host, c'est à dire l'hôte qui a pris en charge le calcul dès que celui-ci passe en mode Running. Cet exec host peut être composé de plusieurs noeuds de calcul, en fonction des ressources nécessaires au run du travail. Lorsque l'on souhaite investiguer sur un batch qui ne s'est pas passé comme on l'attendait, deux options s'offrent à nous pour mettre le doigt sur les noeuds ayant participé à sa résolution :
- une analyse classique de log
- tracejob
$ tracejob 656969 /var/spool/pbs/mom_logs/20110606: No matching job records located /var/spool/pbs/sched_logs/20110606: No such file or directory Job: 656969 06/06/2011 12:29:22 S ready to commit job 06/06/2011 12:29:22 S ready to commit job completed 06/06/2011 12:29:22 S committing job 06/06/2011 12:29:22 S enqueuing into veryshortjour, state 1 hop 1 06/06/2011 12:29:22 S Job Queued at request of kuser@ktux-1, owner = kuser@ktux-1, job name = date, queue = shortday 06/06/2011 12:29:22 A queue=shortday 06/06/2011 12:35:25 S attr Resource_List modified 06/06/2011 12:35:25 S Job Modified at request of root@master 06/06/2011 12:35:25 S Job Run at request of root@master 06/06/2011 12:35:25 S forking in send_job 06/06/2011 12:35:25 S send_job child job pid is 30568 06/06/2011 12:35:25 S entering post_sendmom 06/06/2011 12:35:25 S child reported success for job after 0 seconds (dest=ktux-w1), rc=0 06/06/2011 12:35:25 S attr Resource_List modified 06/06/2011 12:35:25 S Job Modified at request of root@master 06/06/2011 12:35:25 S attr session_id modified 06/06/2011 12:35:25 S sending 'b' mail for job 656969 to kuser@ktux-1 (---) 06/06/2011 12:35:25 A user=kuser group=kuser jobname=date queue=shortday ctime=1307356162 qtime=1307356162 etime=1307356162 start=1307356525 owner=kuser@ktux-1 exec_host=ktux-w1/0 Resource_List.neednodes=ktux-w1 Resource_List.nodect=1 Resource_List.nodes=1:day Resource_List.walltime=00:45:00 06/06/2011 12:35:29 S obit received 06/06/2011 12:35:29 S obit received - updating final job usage info 06/06/2011 12:35:29 S attr resources_used modified 06/06/2011 12:35:29 S job exit status 0 handled 06/06/2011 12:35:29 S sending 'e' mail for job 656969 to kuser@ktux-1 (Exit_status=0 06/06/2011 12:35:29 S Exit_status=0 resources_used.cput=00:00:00 resources_used.mem=0kb resources_used.vmem=0kb resources_used.walltime=00:00:04 06/06/2011 12:35:29 S on_job_exit task assigned to job 06/06/2011 12:35:29 S req_jobobit completed 06/06/2011 12:35:29 S JOB_SUBSTATE_EXITING 06/06/2011 12:35:29 S JOB_SUBSTATE_STAGEOUT 06/06/2011 12:35:29 S about to copy stdout/stderr/stageout files 06/06/2011 12:35:29 S JOB_SUBSTATE_STAGEOUT 06/06/2011 12:35:29 S JOB_SUBSTATE_STAGEDEL 06/06/2011 12:35:29 S JOB_SUBSTATE_EXITED 06/06/2011 12:35:29 S JOB_SUBSTATE_COMPLETE 06/06/2011 12:35:29 S dequeuing from shortday, state COMPLETE 06/06/2011 12:35:29 S removed job script 06/06/2011 12:35:29 S removed job file 06/06/2011 12:35:29 S freeing job 06/06/2011 12:35:29 A user=kuser group=kuser jobname=date queue=shortday ctime=1307356162 qtime=1307356162 etime=1307356162 start=1307356525 owner=kuser@ktux-1 exec_host=ktux-w1/0 Resource_List.neednodes=1:day Resource_List.nodect=1 Resource_List.nodes=1:day Resource_List.walltime=00:45:00 session=24524 end=1307356529 Exit_status=0 resources_used.cput=00:00:00 resources_used.mem=0kb resources_used.vmem=0kb resources_used.walltime=00:00:04
Manipulations de jobs
Bien entendu, on peut manipuler comme bon nous semble les batches ! Pour cela, nous avons tout un éventail de commandes en q.- qdel : suppression du jobID
- qrun : forçage du run du batch, avec options possibles, comme de le faire tourner sur tel et tel noeuds,...
- qalter : modifier les attributs du job : queue, mailing, ...
- qhold : mettre en suspens un job
- qenable/qdisable : activer/désactiver la destination, typiquement une queue particulière
- qstart/qstop : démarrer/arrêter les queues dans le sens où on peut soumettre, mais les jobs enqueued ne sont pas distribués
- ...