¿Cómo ejecutar scripts en paralelo en una máquina remota?

16

Puedo conectarme a una máquina remota que tiene 64 núcleos. Digamos que necesito ejecutar 640 scripts de shell en paralelo en esta máquina. ¿Cómo hago esto?

Puedo ver dividir los 640 scripts en 64 grupos, cada uno de 10 scripts. ¿Cómo podría ejecutar cada uno de estos grupos en paralelo , es decir, un grupo en cada uno de los núcleos disponibles?

Sería un guión de la forma

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

¿dónde script_Acorresponde al primer grupo, script_Bal segundo grupo, etc., es suficiente?

Las secuencias de comandos dentro de un grupo que se ejecutan en un núcleo pueden ejecutarse secuencialmente, pero quiero que los grupos se ejecuten en paralelo en todos los núcleos.

Tom
fuente
No se garantiza que se distribuyan de manera uniforme por los núcleos. Echa un vistazo a este hilo. stackoverflow.com/questions/13583146/…
Rui F Ribeiro

Respuestas:

24

Esto parece un trabajo para GNU paralelo:

parallel bash -c ::: script_*

La ventaja es que no tiene que agrupar sus scripts por núcleos, parallello hará por usted.

Por supuesto, si no desea cuidar a la sesión SSH mientras se ejecutan los scripts, debe usar nohuposcreen

Dmitry Grigoryev
fuente
Es una buena respuesta y la acepto, ya que en el caso general esto funcionaría bien. Desafortunadamente para mí personalmente no tengo privilegios de administrador para la máquina remota y, por lo tanto, no puedo instalar el parallelpaquete. Gracias`
Tom
10
No tiene que instalar paralelo de forma global: debería poder ejecutar una copia desde su propio directorio de inicio.
dhag
bash -cpuede ser que no sean necesarios: parallel ::: ./script*. Con 640 script es probable que sean muy similares (por ejemplo, solo un argumento es diferente). Para eso, considere usar GNU Parallel directamente para establecer estos argumentos y usar un solo script.
Ole Tange
¿Cómo instalaría GNU paralelo en una máquina remota?
Tom
@Tom ¿Qué cambia por el hecho de que estás usando una máquina remota? Simplemente obtenga el paquete correcto de gnu.org/software/parallel e instálelo.
Dmitry Grigoryev
5

Eso funcionará siempre y cuando no necesite monitorear la salida y esté bien dejando abierta su sesión ssh mientras los scripts tarden en ejecutarse. Si alguno de estos no es cierto, recomendaría usarlo screencon varias pestañas. Podrías hacer algo como

screen
for script in script_A script_B script_C; do
  screen -t "$script" ./$script
done;
David King
fuente
Supervisar los resultados que no me preocupan: no me gustaría dejar abierta la sesión ssh. ¿Qué pasa con el uso de nohup? Esto evitaría que los scripts se detengan si la sesión finaliza, ¿no? También echaré un vistazo a tu recomendación de pantalla. ¡Gracias!'
Tom
nohupprobablemente funcionaría, simplemente estoy más familiarizado screeny tiene mucha más funcionalidad que puede o no serle útil.
David King
2

Para iniciar y administrar una gran cantidad de trabajos de secuencias de comandos, necesitará algún tipo de software de administración para controlar el uso de recursos (CPU, memoria, prioridad), ver el estado del trabajo (esperar, suspender, ejecutar, finalizar).

El motor Grid está diseñado para eso, por ejemplo, Sun Grid Engine ( http://wiki.gridengine.info/wiki/index.php/Main_Page ) o Open Grid Scheduler ( http://gridscheduler.sourceforge.net/ ). Es necesario que el administrador instale el software adecuado para usted antes de poder comenzar. El administrador podría estar feliz de hacer eso, en lugar de ver cientos de procesos ejecutándose en la máquina, y no tener control sobre ellos.

En general, el administrador define en cuántas ranuras se puede dividir una máquina, y usted envía un trabajo a una cola y especifica cuántas ranuras quiere consumir el trabajo, el motor de cuadrícula controlará el uso general del sistema y ejecutará el trabajo de acuerdo con La política de colas definida por el administrador. por ejemplo, no se pueden ejecutar más de x trabajos al mismo tiempo, etc. el resto de los trabajos estarán en cola en estado de espera y se liberarán una vez que finalicen los trabajos anteriores.

usuario2912207
fuente
0

Lo he hecho en varias ocasiones y, por lo general, solo paso mi propio script para hacer el trabajo con control de trabajo. Genéricamente, si tiene los nombres de todos los scripts que desea ejecutar en un archivo, la solución se verá así:

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

Es fuerza bruta, pero efectiva. Además, no necesita agregar ningún software adicional como paralelo a sus sistemas.

Un gran problema es que el comando de espera esperará a que finalice el script más lento, lo que puede perder tiempo. He creado guiones para solucionar esta situación, pero se vuelven más complejos como puedes imaginar. Si todos sus scripts se ejecutan en aproximadamente la misma cantidad de tiempo, esto funciona bien.

Otro problema es que puede que tenga que ajustar MAX_PROCS para determinar el mejor rendimiento.

Por supuesto, la cantidad de conexiones ssh puede ser difícil de manejar. En cuyo caso, simplemente mueva este script al host remoto y cambie la línea "ssh ..." para ejecutar los scripts directamente.

Viejo contador de tiempo
fuente