Come eseguire script in parallelo su una macchina remota?


16

Posso ssh in una macchina remota che ha 64 core. Diciamo che devo eseguire 640 script di shell in parallelo su questa macchina. Come faccio a fare questo?

Vedo dividere i 640 script in 64 gruppi ciascuno di 10 script. Come avrei quindi eseguito ciascuno di questi gruppi in parallelo , ovvero un gruppo su ciascuno dei core disponibili.

Sarebbe una sceneggiatura del modulo

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

dove script_Acorrisponde al primo gruppo, script_Bal secondo gruppo ecc., è sufficiente?

Gli script all'interno di un gruppo eseguiti su un core possono essere eseguiti in sequenza, ma voglio che i gruppi vengano eseguiti in parallelo su tutti i core.


Non è garantito che siano distribuiti uniformemente dai nuclei. Dai un'occhiata a questa discussione. stackoverflow.com/questions/13583146/…
Rui F Ribeiro,

Risposte:


24

Sembra un lavoro per gnu parallel:

parallel bash -c ::: script_*

Il vantaggio è che non devi raggruppare i tuoi script per core, parallello farà per te.

Naturalmente, se non si desidera fare da babysitter alla sessione SSH mentre gli script sono in esecuzione, è necessario utilizzare nohuposcreen


È una buona risposta e la accetto come in generale funzionerebbe bene. Sfortunatamente per me personalmente non ho i privilegi di amministratore per la macchina remota e quindi non posso installare il parallelpacchetto. Grazie`
Tom,

10
Non è necessario installare parallelamente a livello globale: si dovrebbe essere in grado di eseguire una copia dalla propria directory home.
Dhag,

bash -cpuò essere non necessari: parallel ::: ./script*. Con 640 script è probabile che siano molto simili (es. Solo un argomento è diverso). Per questo considera di usare GNU Parallel direttamente per impostare questi argomenti e usare un singolo script.
Ole Tange il

Come installerei gnu parallel su una macchina remota?
Tom,

@ Tom Che cosa cambia dal fatto che stai utilizzando un computer remoto? Basta ottenere il pacchetto giusto da gnu.org/software/parallel e installarlo.
Dmitry Grigoryev il

5

Funzionerà finché non avrai bisogno di monitorare l'output e stai bene lasciando aperta la sessione ssh per tutto il tempo necessario per l'esecuzione degli script. Se uno di questi non fosse vero, consiglierei l'uso screencon più schede. Potresti fare qualcosa del genere

screen
for script in script_A script_B script_C; do
  screen -t "$script" ./$script
done;

Monitoraggio degli output di cui non mi preoccupo: non vorrei lasciare aperta la sessione SSH. Che dire di usare nohup? Ciò impedirebbe l'arresto degli script se la sessione è terminata no? Daremo anche un'occhiata alla tua "raccomandazione sullo schermo. Grazie!'
Tom,

nohupprobabilmente funzionerebbe, ho solo più familiarità con screene ha molte più funzionalità che potrebbero esserti utili o meno.
David King,

2

Per dare il via e gestire un gran numero di lavori di scripting, avrai bisogno di una sorta di software di gestione per controllare l'utilizzo delle risorse (CPU, memoria, priorità), vedere lo stato del lavoro (attendere, sospendere, eseguire, terminato).

Grid engine è stato creato per questo, ad esempio Sun Grid Engine ( http://wiki.gridengine.info/wiki/index.php/Main_Page ) o Open Grid Scheduler ( http://gridscheduler.sourceforge.net/ ). È necessario che l'amministratore installi il software adeguato prima di poter iniziare. L'amministratore potrebbe essere felice di farlo, invece di vedere centinaia di processi in esecuzione sul computer e non avere alcun controllo su di essi.

In generale, l'amministratore definisce il numero di slot in cui una macchina può essere suddivisa e si invia un lavoro a una coda e si specifica il numero di slot che il lavoro vuole consumare, il motore di griglia monitorerà l'utilizzo complessivo del sistema ed eseguirà il lavoro in base a la politica di accodamento definita dall'amministratore. ad es. non è possibile eseguire contemporaneamente più di x lavori, ecc. gli altri lavori saranno in coda in stato di attesa e rilasciati al termine dei lavori precedenti.



0

L'ho fatto in diverse occasioni e di solito basta girare il mio script per fare il lavoro con il controllo del lavoro. Generalmente se si hanno i nomi di tutti gli script che si desidera eseguire in un file, la soluzione è simile a:

#!/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

È forza bruta, ma efficace. Inoltre non è necessario aggiungere alcun software aggiuntivo come parallelo ai tuoi sistemi.

Un grosso problema è che il comando wait attende che finisca lo script più lento, il che può far perdere tempo. Ho creato degli script per gestire questa situazione, ma diventano più complessi come puoi immaginare. Se tutti i tuoi script vengono eseguiti nello stesso lasso di tempo, questo funziona bene.

Un altro problema è che potrebbe essere necessario ottimizzare MAX_PROCS per determinare le prestazioni migliori.

Naturalmente, il numero di connessioni ssh può diventare ingombrante. Nel qual caso basta spostare questo script sull'host remoto e cambiare la riga "ssh ..." per eseguire direttamente gli script.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.