Comment exécuter des scripts en parallèle sur une machine distante?

16

Je peux ssh dans une machine distante qui a 64 cœurs. Disons que je dois exécuter 640 scripts shell en parallèle sur cette machine. Comment puis-je faire cela?

Je peux voir la division des 640 scripts en 64 groupes chacun de 10 scripts. Comment pourrais-je alors exécuter chacun de ces groupes en parallèle , c'est-à-dire un groupe sur chacun des cœurs disponibles?

Serait un script de la forme

    ./script_A &
    ./script_B &
    ./script_C &
    ...

script_Acorrespond au premier groupe, script_Bau deuxième groupe etc., suffit?

Les scripts au sein d'un groupe qui s'exécutent sur un cœur sont autorisés à s'exécuter séquentiellement, mais je veux que les groupes s'exécutent en parallèle sur tous les cœurs.

À M
la source
Il n'est pas garanti qu'ils soient répartis uniformément par les cœurs. Jetez un oeil à ce fil. stackoverflow.com/questions/13583146/…
Rui F Ribeiro

Réponses:

24

Cela ressemble à un travail pour GNU Parallel:

parallel bash -c ::: script_*

L'avantage est que vous n'avez pas à regrouper vos scripts par cœurs, cela parallelse fera pour vous.

Bien sûr, si vous ne voulez pas garder la session SSH pendant l'exécution des scripts, vous devez utiliser nohupouscreen

Dmitry Grigoryev
la source
C'est une bonne réponse et je l'accepte car dans le cas général, cela fonctionnerait bien. Malheureusement pour moi personnellement, je n'ai pas de privilèges d'administrateur sur la machine distante et je ne peux donc pas installer le parallelpackage. Merci`
Tom
10
Vous n'avez pas besoin d'installer parallèlement globalement: vous devriez pouvoir exécuter une copie à partir de votre propre répertoire personnel.
dhag
bash -cpeut être inutile: parallel ::: ./script*. Avec 640 scripts, il est probable qu'ils soient très similaires (par exemple, seul un argument est différent). Pour cela, envisagez d'utiliser GNU Parallel directement pour définir ces arguments et utilisez un seul script.
Ole Tange
Comment installer gnu parallel sur une machine distante?
Tom
@Tom Qu'est-ce qui est changé par le fait que vous utilisez une machine distante? Obtenez simplement le bon package sur gnu.org/software/parallel et installez.
Dmitry Grigoryev
5

Cela fonctionnera tant que vous n'aurez pas besoin de surveiller la sortie et que vous serez d'accord pour laisser votre session ssh ouverte aussi longtemps que les scripts prendront pour s'exécuter. Si l'un ou l'autre n'est pas vrai, je recommanderais de l'utiliser screenavec plusieurs onglets. Vous pourriez faire quelque chose comme

screen
for script in script_A script_B script_C; do
  screen -t "$script" ./$script
done;
David King
la source
Surveiller les sorties qui ne me concernent pas - je ne voudrais pas laisser la session ssh ouverte. Et si vous utilisiez nohup? Cela empêcherait les scripts de s'arrêter si la session se termine non? J'examinerai également votre recommandation d'écran. Merci!'
Tom
nohupfonctionnerait probablement, je suis juste plus familier screenet il a beaucoup plus de fonctionnalités qui peuvent ou non vous être utiles.
David King
2

Pour lancer et gérer un grand nombre de travaux de script, vous aurez besoin d'une sorte de logiciel de gestion pour contrôler l'utilisation des ressources (CPU, mémoire, priorité), voir l'état du travail (attendre, suspendre, exécuter, terminé).

Le moteur de grille est conçu pour cela, par exemple, Sun Grid Engine ( http://wiki.gridengine.info/wiki/index.php/Main_Page ) ou Open Grid Scheduler ( http://gridscheduler.sourceforge.net/ ). Vous avez besoin de l'administrateur pour installer le logiciel approprié pour vous avant de commencer. L'administrateur peut être heureux de le faire, au lieu de voir des centaines de processus s'exécuter sur la machine, et n'a aucun contrôle sur eux.

En général, l'administrateur définit le nombre d'emplacements dans lesquels une machine peut être divisée, et vous soumettez un travail à une file d'attente et spécifiez le nombre d'emplacements que le travail veut consommer, le moteur de grille surveillera l'utilisation globale du système et exécutera le travail selon la politique de mise en file d'attente définie par l'administrateur. Par exemple, pas plus de x travaux peuvent s'exécuter en même temps, etc. le reste des travaux sera dans la file d'attente en état d'attente et libéré après la fin des travaux précédents.

user2912207
la source
0

Je l'ai fait à plusieurs reprises et je lance généralement mon propre script pour faire le travail avec le contrôle des travaux. De manière générique, si vous avez les noms de tous les scripts que vous souhaitez exécuter dans un fichier, la solution ressemble à:

#!/bin/bash
scripts=$(cat scriptfiles.txt)
declare -i NUM=0
declare -i MAX_PROCS=30
for script in "$scripts"
do
  NUM=$((NUM+1))
  ssh remote.host.ip "${script}" > ${script}.log 2>&1 &
  if [ $NUM -ge $MAX_PROCS ];then
    echo "Waiting for $NUM processes to finish."
    wait
    NUM=0
  fi
done
echo "Waiting for final $NUM processes to finish."
wait
exit

C'est de la force brute, mais efficace. De plus, vous n'avez pas besoin d'ajouter de logiciel supplémentaire comme Parallel à vos systèmes.

Un gros problème est que la commande wait attendra la fin du script le plus lent, ce qui peut perdre du temps. J'ai créé des scripts pour gérer cette situation, mais ils deviennent plus complexes comme vous pouvez l'imaginer. Si tous vos scripts s'exécutent dans le même laps de temps, cela fonctionne bien.

Un autre problème est que vous devrez peut-être régler MAX_PROCS pour déterminer les meilleures performances.

Bien sûr, le nombre de connexions ssh peut devenir lourd. Dans ce cas, déplacez simplement ce script vers l'hôte distant et modifiez la ligne "ssh ..." pour exécuter directement les scripts.

OldTimer
la source