Fondamenti di scheduler
Ultimo aggiornamento il 2025-08-04 | Modifica questa pagina
Panoramica
Domande
- Cos’è uno scheduler e perché un cluster ne ha bisogno?
- Come si lancia un programma da eseguire su un nodo di calcolo del cluster?
- Come posso catturare l’output di un programma eseguito su un nodo del cluster?
Obiettivi
- Invia un semplice script al cluster.
- Monitorare l’esecuzione dei lavori utilizzando gli strumenti della riga di comando.
- Ispezionare i file di output e di errore dei lavori.
- Trovare il posto giusto per mettere grandi insiemi di dati sul cluster.
Programmatore di lavoro
Un sistema HPC può avere migliaia di nodi e migliaia di utenti. Come si decide chi riceve cosa e quando? Come facciamo a garantire che un task venga eseguito con le risorse di cui ha bisogno? Questo lavoro è gestito da uno speciale software chiamato scheduler. In un sistema HPC, lo scheduler gestisce i lavori da eseguire dove e quando.
L’illustrazione seguente paragona i compiti di uno schedulatore di lavori a quelli di un cameriere in un ristorante. Se vi è capitato di dover aspettare un po’ in coda per entrare in un ristorante famoso, allora potete capire perché a volte i vostri lavori non partono immediatamente come nel vostro portatile.
Lo scheduler utilizzato in questa lezione è Slurm. Sebbene Slurm non sia utilizzato ovunque, l’esecuzione dei lavori è abbastanza simile indipendentemente dal software utilizzato. La sintassi esatta può cambiare, ma i concetti rimangono gli stessi.
Esecuzione di un lavoro batch
L’uso più semplice dello scheduler è quello di eseguire un comando in modo non interattivo. Qualsiasi comando (o serie di comandi) che si desidera eseguire sul cluster è chiamato lavoro e il processo di utilizzo dello schedulatore per eseguire il lavoro è chiamato invio di lavori in batch.
In questo caso, il lavoro da eseguire è uno script di shell, ovvero un file di testo contenente un elenco di comandi UNIX da eseguire in modo sequenziale. Il nostro script di shell sarà composto da tre parti:
- Alla prima riga, aggiungere
#!/bin/bash
. L’opzione#!
(pronunciata “hash-bang” o “shebang”) indica al computer quale programma deve elaborare il contenuto di questo file. In questo caso, gli stiamo dicendo che i comandi che seguono sono scritti per la shell a riga di comando (con cui abbiamo fatto tutto finora). - in qualsiasi punto sotto la prima riga, aggiungeremo un comando
echo
con un saluto amichevole. Una volta eseguito, lo script di shell stamperà nel terminale qualsiasi cosa venga dopoecho
.-
echo -n
stamperà tutto ciò che segue, senza terminare la riga stampando il carattere di nuova riga.
-
- Nell’ultima riga, invocheremo il comando
hostname
, che stamperà il nome della macchina su cui viene eseguito lo script.
Creare il nostro lavoro di prova
Eseguire lo script. Viene eseguito sul cluster o solo sul nostro nodo di accesso?
Questo script è stato eseguito sul nodo di login, ma vogliamo
sfruttare i nodi di calcolo: abbiamo bisogno che lo scheduler metta in
coda example-job.sh
per eseguirlo su un nodo di
calcolo.
Per inviare questo task allo scheduler, si usa il comando
sbatch
. Questo crea un lavoro che eseguirà il
script quando verrà spedito a un nodo di calcolo che
il sistema di accodamento ha identificato come disponibile per eseguire
il lavoro.
OUTPUT
Submitted batch job 7
E questo è tutto ciò che dobbiamo fare per inviare un lavoro. Il
nostro lavoro è finito: ora lo scheduler prende il sopravvento e cerca
di eseguire il lavoro per noi. Mentre il lavoro è in attesa di essere
eseguito, viene inserito in un elenco di lavori chiamato queue.
Per verificare lo stato del nostro lavoro, controlliamo la coda usando
il comando squeue -u yourUsername
.
OUTPUT
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
9 cpubase_b example- user01 R 0:05 1 node1
Possiamo vedere tutti i dettagli del nostro lavoro, soprattutto che è
nello stato R
o RUNNING
. A volte i nostri
lavori potrebbero dover aspettare in coda (PENDING
) o avere
un errore (E
).
Dov’è l’output?
Nel nodo di accesso, questo script stampava l’output nel terminale,
ma ora, quando squeue
mostra che il lavoro è terminato, non
viene stampato nulla nel terminale.
L’output del lavoro del cluster viene solitamente reindirizzato a un
file nella directory da cui è stato lanciato. Usare ls
per
trovare e cat
per leggere il file.
Personalizzazione di un lavoro
Il lavoro appena eseguito ha utilizzato tutte le opzioni predefinite dello schedulatore. In uno scenario reale, probabilmente non è quello che vogliamo. Le opzioni predefinite rappresentano un minimo ragionevole. È probabile che avremo bisogno di più core, più memoria, più tempo e altre considerazioni speciali. Per avere accesso a queste risorse, dobbiamo personalizzare il nostro script di lavoro.
I commenti negli script di shell UNIX (indicati con #
)
sono generalmente ignorati, ma ci sono delle eccezioni. Per esempio, il
commento speciale #!
all’inizio degli script specifica
quale programma deve essere usato per eseguirli (di solito si vede
#!/usr/bin/env bash
). Anche gli schedulatori, come Slurm,
hanno un commento speciale usato per indicare opzioni specifiche dello
schedulatore. Sebbene questi commenti differiscano da schedulatore a
schedulatore, il commento speciale di Slurm è #SBATCH
.
Tutto ciò che segue il commento #SBATCH
viene interpretato
come un’istruzione per lo schedulatore.
Illustriamo questo esempio. Per impostazione predefinita, il nome di
un lavoro è il nome dello script, ma l’opzione -J
può
essere usata per cambiare il nome di un lavoro. Aggiungere un’opzione
allo script:
Inviare il lavoro e monitorarne lo stato:
OUTPUT
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
10 cpubase_b hello-wo user01 R 0:02 1 node1
Fantastico, abbiamo cambiato con successo il nome del nostro lavoro!
Richieste di risorse
Che dire di cambiamenti più importanti, come il numero di core e di memoria per i nostri lavori? Una cosa assolutamente fondamentale quando si lavora su un sistema HPC è specificare le risorse necessarie per eseguire un lavoro. Questo permette allo scheduler di trovare il momento e il posto giusto per programmare il nostro lavoro. Se non si specificano i requisiti (ad esempio la quantità di tempo necessaria), è probabile che si rimanga bloccati con le risorse predefinite del sito, il che probabilmente non è ciò che si desidera.
Le seguenti sono diverse richieste di risorse chiave:
--ntasks=<ntasks>
o-n <ntasks>
: Di quanti core di CPU ha bisogno il vostro lavoro, in totale?--time <days-hours:minutes:seconds>
o-t <days-hours:minutes:seconds>
: Quanto tempo reale (walltime) impiegherà il lavoro per essere eseguito? La parte<days>
può essere omessa.--mem=<megabytes>
: Di quanta memoria su un nodo ha bisogno il lavoro in megabyte? Si possono anche specificare i gigabyte aggiungendo una piccola “g” dopo (esempio:--mem=5g
)--nodes=<nnodes>
o-N <nnodes>
: Su quante macchine separate deve essere eseguito il lavoro? Si noti che se si impostantasks
su un numero superiore a quello che può offrire una sola macchina, Slurm imposterà automaticamente questo valore.
Si noti che il solo fatto di richiedere queste risorse non rende il lavoro più veloce, né significa necessariamente che si consumeranno tutte queste risorse. Significa solo che vengono messe a disposizione. Il lavoro può finire per utilizzare meno memoria, meno tempo o meno nodi di quelli richiesti, ma verrà comunque eseguito.
È meglio che le richieste riflettano accuratamente i requisiti del lavoro. In una puntata successiva di questa lezione parleremo di come assicurarsi di utilizzare le risorse in modo efficace.
Invio di richieste di risorse
Modificare il nostro script hostname
in modo che venga
eseguito per un minuto, quindi inviare un lavoro per esso sul
cluster.
Le richieste di risorse sono in genere vincolanti. Se si superano, il lavoro viene eliminato. Utilizziamo il tempo di parete come esempio. Richiederemo 1 minuto di tempo di parete e cercheremo di eseguire un lavoro per due minuti.
BASH
#!/bin/bash
#SBATCH -J long_job
#SBATCH -t 00:01 # timeout in HH:MM
echo "This script is running on ... "
sleep 240 # time in seconds
hostname
Inviare il lavoro e attendere che finisca. Una volta terminato, controllare il file di log.
OUTPUT
This script is running on ...
slurmstepd: error: *** JOB 12 ON node1 CANCELLED AT 2021-02-19T13:55:57
DUE TO TIME LIMIT ***
Il nostro lavoro è stato annullato per aver superato la quantità di risorse richieste. Anche se questo sembra un problema, in realtà si tratta di una caratteristica. Il rispetto rigoroso delle richieste di risorse consente allo scheduler di trovare il miglior posto possibile per i lavori. Ancora più importante, garantisce che un altro utente non possa utilizzare più risorse di quelle che gli sono state assegnate. Se un altro utente sbaglia e tenta accidentalmente di usare tutti i core o la memoria di un nodo, Slurm limiterà il suo lavoro alle risorse richieste o lo ucciderà del tutto. Gli altri lavori sul nodo non ne risentiranno. Ciò significa che un utente non può rovinare l’esperienza degli altri: gli unici lavori interessati da un errore di programmazione saranno i propri.
Annullamento di un lavoro
A volte capita di commettere un errore e di dover cancellare un
lavoro. Questo può essere fatto con il comando scancel
.
Inviamo un lavoro e poi annulliamolo usando il suo numero di lavoro
(ricordate di cambiare il tempo di esecuzione in modo che funzioni
abbastanza a lungo da permettervi di annullarlo prima che venga
ucciso).
OUTPUT
Submitted batch job 13
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
13 cpubase_b long_job user01 R 0:02 1 node1
Ora annullate il lavoro con il suo numero (stampato nel terminale). Un ritorno pulito del prompt dei comandi indica che la richiesta di annullamento del lavoro è andata a buon fine.
BASH
[yourUsername@login1 ~] scancel 38759
# It might take a minute for the job to disappear from the queue...
[yourUsername@login1 ~] squeue -u yourUsername
OUTPUT
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
Annullamento di lavori multipli
È anche possibile cancellare tutti i lavori in una volta sola usando
l’opzione -u
. In questo modo si cancellano tutti i lavori
di un utente specifico (in questo caso, l’utente stesso). Si noti che è
possibile cancellare solo i propri lavori.
Provare a inviare più lavori e poi annullarli tutti.
Altri tipi di lavoro
Finora ci siamo concentrati sull’esecuzione di lavori in modalità
batch. Slurm
offre anche la possibilità di avviare una
sessione interattiva.
Molto spesso ci sono compiti che devono essere eseguiti in modo
interattivo. Creare un intero script di lavoro potrebbe essere
eccessivo, ma la quantità di risorse richieste è troppo elevata per
essere gestita da un nodo di login. Un buon esempio potrebbe essere la
creazione di un indice del genoma per l’allineamento con uno strumento
come HISAT2.
Fortunatamente, è possibile eseguire questo tipo di compiti una tantum
con srun
.
srun
esegue un singolo comando sul cluster e poi esce.
Dimostriamo questo eseguendo il comando hostname
con
srun
. (È possibile annullare un lavoro srun
con Ctrl-c
)
OUTPUT
smnode1
srun
accetta tutte le stesse opzioni di
sbatch
. Tuttavia, invece di specificarle in uno script,
queste opzioni vengono specificate sulla riga di comando quando si avvia
un lavoro. Per inviare un lavoro che utilizza 2 CPU, ad esempio, si può
usare il seguente comando:
OUTPUT
This job will use 2 CPUs.
This job will use 2 CPUs.
In genere, l’ambiente di shell risultante sarà lo stesso di quello di
sbatch
.
Lavori interattivi
A volte si ha bisogno di molte risorse per l’uso interattivo. Forse è
la prima volta che si esegue un’analisi o si sta cercando di eseguire il
debug di qualcosa che è andato storto con un lavoro precedente.
Fortunatamente, Slurm semplifica l’avvio di un lavoro interattivo con
srun
:
Dovrebbe apparire un prompt di bash. Si noti che il prompt
probabilmente cambierà per riflettere la nuova posizione, in questo caso
il nodo di calcolo su cui si è effettuato l’accesso. Si può anche
verificare con hostname
.
Creazione della grafica remota
Per vedere l’output grafico dei lavori, è necessario utilizzare
l’inoltro X11. Per connettersi con questa funzione abilitata, usare
l’opzione -Y
quando si effettua il login con il comando
ssh
, ad esempio,
ssh -Y yourUsername@cluster.hpc-carpentry.org
.
Per dimostrare cosa succede quando si crea una finestra grafica sul
nodo remoto, usare il comando xeyes
. Dovrebbe apparire un
paio di occhi relativamente adorabili (premere Ctrl-C
per
fermarsi). Se si utilizza un Mac, è necessario aver installato XQuartz
(e riavviato il computer) perché questo funzioni.
Se nel cluster è installato il plugin slurm-spank-x11,
si può garantire l’inoltro X11 nei lavori interattivi usando l’opzione
--x11
per srun
con il comando
srun --x11 --pty bash
.
Al termine del lavoro interattivo, digitare exit
per
uscire dalla sessione.
Punti Chiave
- Lo scheduler gestisce la condivisione delle risorse di calcolo tra gli utenti.
- Un lavoro è solo uno script di shell.
- Richiedere poco più risorse di quelle necessarie.