Avec les avancées en biologie ces dernières années, la quantité de données produites et les ressources informatiques nécessaires à leur traitement ont grandement augmenté. Pour faire face à ces problèmes, l'une des solutions les plus répandues est la mise en place de grappes de serveurs (plus souvent désignées par le terme anglais computer cluster ou simplement cluster). Sur ces systèmes, les commandes à exécuter sont soumises à un gestionnaire de ressources qui répartit les tâches sur les ordinateurs du cluster. Il existe plusieurs solutions sur le marché, mais leur comportement est souvent similaire.
Aujourd'hui je vais utiliser l'une d'entre elles, Load Sharing Facility (LSF), comme exemple pour vous présenter certaines règles essentielles au bon fonctionnement d'un cluster. Cela s'adresse aux personnes débutantes sur ce type de système, mais également à ceux qui n'ont pas eu de formation avant de travailler sur un cluster.
C'est quoi une grappe ?
Une grappe est un réseau d'ordinateurs, indépendants et interconnectés, gérés tous ensemble comme une seule ressource informatique. Cette structure offre l'avantage d'additionner les ressources de toutes les machines ainsi connectées dans un seul système. Par exemple, sur un cluster composé de deux machines ayant 24 processeurs et 100 Go de mémoire vive chacune, il sera possible d'exécuter une tâche utilisant 48 processeurs et 200 Go de mémoire. L'exemple donné est sur deux machines identiques, mais une grappe peut être composée d'ordinateurs aux capacités différentes (pour en savoir plus : La page wikipédia sur les grappes). Bien sur c'est un système complexe à gérer et il existe pour cela différents gestionnaires de ressources sur le marché.
Le gestionnaire de ressources
Avoir un cluster c'est bien, mais il faut aussi pouvoir le gérer efficacement. La personne responsable de la mise en place du système va choisir les règles, qui s'appliqueront aux utilisateurs, grâce au gestionnaire de ressources. Chaque administrateur a sa façon de faire, qui peut être plus ou moins restrictive. Je vais détailler ici uniquement les règles qui concernent les utilisateurs et plus particulièrement celles que j'ai rencontrées. Je fais cette précision car je n'ai certainement pas rencontré tout les formes de restriction et il vous faudra peut-être apprendre à gérer d'autres règles.
Habituellement, en tant qu'utilisateur, on n'a à se soucier que de cinq ou six valeurs. Les plus évidentes sont celles que l'on retrouve sur tout système informatique, combien d'espace sur le disque, de mémoire vive et de CPU sont à disposition. A celles-ci s'ajoutent le nombre de tâches que l'on peut lancer simultanément et la limite dans le temps pour celles-ci. C'est principalement ces options que l'administrateur aura limité pour éviter tout abus. Si le travail est bien fait, l'utilisateur aura plusieurs options, comme lancer un travail très intensif (beaucoup de mémoire et de CPU) mais qui devra être court ou au contraire, lancer une tâche légère mais qui pourra tourner sur plusieurs jours. Ces choix sont représentés par ce qu'on appelle les queues, celle-ci sont mise en place par l'administrateur et correspondent chacune à différents besoins et en conséquence à différentes règles. On peut par exemple imaginer un système avec deux queues ; la queue « longue » qui permettra de lancer un travail sur 8 CPU mais sans limite de temps et la queue « normale » qui permettra de lancer un job sur 64 CPU mais celui-ci ne pourra pas durer plus de 24h. C'est ensuite à l'utilisateur de choisir correctement dans quelle queue sa tâche devra aller.
Soumettre un travail au cluster
Pour travailler sur une grappe, l’utilisateur s'y connecte en SSH, il pourra ensuite travailler comme sur n'importe quel autre système. Toutes les commandes qui vont suivre fonctionnement sur le système LSF, les commandes pour les autres gestionnaires de ressources sont facilement trouvables sur Internet et vous seront très probablement présentées le jour où vous devrez travailler sur un cluster. Cependant, les règles que je vais présenter devraient être appliquées par tous les utilisateurs, quel que soit le gestionnaire utilisé.
Si l'administrateur ne vous a pas donné assez d'informations sur le système, vous pouvez commencer par vérifier quelles queues sont disponibles et quelles sont les règles qui s'y appliquent. Pour cela, utilisez la commande suivante :
1 |
[crayon-672342aa82e2d627948311 ]bqueues -l |
La commande bqueue sans l'option « -l » donne un petit résumé, bien utile, du statut des queues, combien de jobs tournent et combien sont en attente, sur chacune d'entre elles. Avec l'option « ‑l » elle donne tous les détails sur les limites (mémoire, cpu, temps, nombre de tâches simultanées…) qui s'appliquent aux queues mises en place par l'administrateur.
Maintenant que vous connaissez mieux le système, vous pouvez exécuter vos premières commandes sur le cluster. A première vue, cela peut paraître effrayant, toute cette puissance et toutes ces règles… « Lancer une tâche sur un cluster doit être affreusement compliqué ! »
1 |
bsub 'ls ‑l' |
# Attention, à ne pas reproduire chez vous. Lire la suite pour comprendre pourquoi.
Pour les nouveaux sur GNU/Linux. La commande 'ls' sert à lister le contenu de votre dossier.
Je viens de demander au cluster de lister le contenu du dossier courant. 'bsub » (sub pour submit) est la commande qui envoie une tâche se faire exécuter sur la grappe. Le gestionnaire va alors vérifier si il y a la place pour lancer la commande et l'exécutera si c'est le cas. Ici la commande est tellement petite qu'elle sera, presque à coup sûr, lancée immédiatement. Et voici un premier conseil, n'utilisez pas une grappe pour faire un travail, comme celui-ci, qui peut tourner sur un simple ordinateur. Rien ne vous empêchera de la faire, mais c'est contre-productif, trop de puissance est utilisée pour une simple tâche.
Bsub est donc la commande magique pour envoyer un travail sur le cluster. Je vais ici détailler les options qui permettent de lancer un travail proprement :
1 |
bsub -o output_file -e error_file -q normal -M 10000000 -n 12 -R 'rusage[mem=10000]' 'ma_commande' |
Les options « ‑o » et « ‑e » prennent comme argument le nom d'un fichier. Si ces options sont utilisées, le rapport d'exécution de la commande et les éventuelles erreurs rencontrées seront écrits dans ces fichiers. Le rapport donne des informations sur la mémoire et les CPU utilisés par la commande, cela servira à optimiser les prochaines commandes. Le rapport d'erreur permettra éventuellement de comprendre ce qui n'a pas marché.
L'option « -q » permet de choisir sur quelle queue le travail sera lancé. A l'utilisateur de choisir en fonction des besoins.
Les options « ‑n » et « -R » informent le cluster des ressources utilisées par la commande, respectivement le nombre de CPU et la quantité de mémoire (en MB). La commande pourrait éventuellement fonctionner sans ces deux options, mais il s'agit ici d'informer le système pour éviter l'encombrement. En l'absence de ces options, le système considérera que le job utilise un seul slot. Un slot est une unité de travail sur le cluster, l'administrateur détermine à quoi cela correspond. Cela pourrait par exemple être 2 GB de mémoire et 1 CPU. Dans ce cas si les options « ‑n » et « -R » ne sont pas données et que la commande précédente est exécutée, le système pensera utiliser 2 GB alors que la commande utilise 10 GB. Si tout le monde agit ainsi, le système sera très vite surchargé.
L'option « ‑M » entre dans une autre catégorie. Elle permet de fixer la limite de mémoire à utiliser pour cette commande. En effet, l'administrateur peut décider qu'en absence d'information, un job n'utilise pas plus de mémoire que 2 GB. Dans ce cas, si une commande utilise 3 GB et que l'option « ‑M » n'a pas été donnée, le système tue la commande quand elle dépasse les 2 GB de mémoire utilisée. Il existe plusieurs autres options comme celle-ci, pour le nombre de CPU, le temps d'exécution… Je vous laisse les découvrir par vous-même si votre système l'exige.
Finalement, une dernière commande qui peut servir pour débuter sur un cluster :
1 |
bjobs |
Celle-ci liste les jobs que l'utilisateur a soumis au cluster et donne leur statut (pending, running, exit…). Elle peut prendre différentes options pour lister de façon plus précise vos tâches (queue, statut…).
Exemple
Voici un exemple des commandes décrites dans le paragraphe précédent, avec leur résultat.
1 2 3 4 5 6 7 8 9 10 11 |
$bqueues QUEUE_NAME PRIO STATUS MAX JL/U JL/P JL/H NJOBS PEND RUN SUSP priority 30 Open:Active — 400 2 — 0 0 0 0 normal 20 Open:Active — 256 1 — 68 49 19 0 interactive 20 Open:Active — 3 1 — 1 0 1 0 long 20 Open:Active — 100 1 — 71 0 71 0 |
Il y a donc 4 queues sur ce système. Un utilisateur peut avoir 256 jobs tournant simultanément sur la queue 'normale'. Actuellement 68 tâches ont été soumises à cette queue et 19 tournent sur le cluster.
Maintenant demandons au cluster d'exécuter un job sur la queue 'long', en l'informant que la commande utilisera environ 5GB de mémoire vive.
1 2 |
$bsub -q long -M 5000000 -R "rusage[mem=5000]" 'tar xzf fastq.tar.gz'<br> Job < ;979151> ; is submitted to queue < ;long> ;. |
Vérifions l'état de notre job avec la commande « bjobs ‑all » qui affiche les détails de notre tâche, la commande, le dossier d'où elle est lancée, l'utilisateur, la mémoire utilisée…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$bjobs ‑all 979151 Job <979151>, User <bob>, Project <default>, Status <RUN>, Queue <long>, Command <tar xzf fastq.tar.gz>, Share group charged </bob> Wed Jul 11 10:00:29 : Submitted from host <front-end>, CWD </data>, Re-runnable ; Wed Jul 11 10:00:35 : Started on <cpt07>, Execution Home </home/bob>, Execution CWD </data>; Requested Resources <rusage[mem=5000]>; MEMLIMIT 5000000 K Wed Jul 11 10:00:52 : Resource usage collected. MEM : 4320 Mbytes ; SWAP : 28 Mbytes ; NTHREAD : 1 PGID : 3317 ; PIDs : 3317 SCHEDULING PARAMETERS : r15s r1m r15m ut pg io ls it tmp swp mem loadSched — — — — — — — — — — - loadStop — — — — — — — — — — - |
Récapitulatif
Commandes :
bsub : soumettre un job
- « ‑o file » et « ‑e file » : permettent d'ecrire le standard output et standard error dans un fichier
- « ‑q nom_queue » : permet de préciser sur quelle queue le job tournera
- « ‑M 1000 » : limite de mémoire vive (en KB)
- « ‑R 'rusage[mem=1000]' » : informe le cluster de la mémoire utilisée par le job (en MB)
- « ‑n 2 »: informe le cluster sur le nombre de cœurs utilisés
- « ‑o file » et « ‑e file » : permettent d'ecrire le standard output et standard error dans un fichier
- bjobs : lister les job soumis au cluster
- bqueues : informations sur les queues
Conseils :
1- Ne pas lancer de trop petites tâches sur un cluster,
2- Vérifier les différentes queues proposées,
3- Toujours informer le cluster de l'énergie requise par une commande, pour éviter les surcharges.
Voilà qui, je l'espère, devrait vous permettre de commencer à travailler proprement sur un cluster. N'oubliez pas que la liste de conseils donnée ici n'est pas exhaustive. A vous d'être responsable et d'utiliser votre cluster de la façon la plus civique possible. J'espère aussi avoir rassuré ceux qui avaient peur à l'idée de travailler sur ce type de machine, cela n'a vraiment rien de compliqué. Je ferais peut-être un article sur des exemples d'utilisations plus avancées, si cet article suscite un intérêt. Et bien sûr comme d'habitude, n'hésitez pas à donner vos conseils dans les commentaires, pour une meilleure utilisation des clusters.
Laisser un commentaire