Como executar scripts em paralelo em uma máquina remota?

16

Eu posso ssh em uma máquina remota que tenha 64 núcleos. Vamos dizer que eu preciso executar 640 scripts de shell em paralelo nesta máquina. Como faço isso?

Eu posso dividir os 640 scripts em 64 grupos de 10 scripts. Como eu então executaria cada um desses grupos em paralelo , ou seja, um grupo em cada um dos núcleos disponíveis.

Seria um script do formulário

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

onde script_A corresponde ao primeiro grupo, script_B ao segundo grupo etc., é suficiente?

Os scripts dentro de um grupo que são executados em um núcleo são ok para serem executados sequencialmente, mas eu quero que os grupos sejam executados em paralelo em todos os núcleos.

    
por Tom 09.12.2015 / 14:39

5 respostas

24

Isto parece um trabalho para o gnu paralelo:

parallel bash -c ::: script_*

A vantagem é que você não precisa agrupar seus scripts por núcleos, parallel fará isso para você.

Claro, se você não quiser tomar conta da sessão SSH enquanto os scripts estiverem em execução, use nohup ou screen

    
por 09.12.2015 / 15:00
5

Isso funcionará desde que você não precise monitorar a saída e você está bem deixando sua sessão ssh aberta pelo tempo que os scripts levarem para rodar. Se algum deles não for verdadeiro, recomendo usar screen com várias guias. Você poderia fazer algo como

screen
for script in script_A script_B script_C; do
  screen -t "$script" ./$script
done;
    
por 09.12.2015 / 14:51
2

Para iniciar e gerenciar um grande número de tarefas de script, você precisará de algum tipo de software de gerenciamento para controlar o uso de recursos (CPU, memória, prioridade) e ver o status do trabalho (aguardar, suspender, executar, concluir).

O mecanismo de grade é criado para isso, por exemplo, o Sun Grid Engine ( link ) ou o Open Grid Agendador ( link ). Você precisa do administrador para instalar o software adequado para você antes de começar. O administrador pode ficar feliz em fazer isso, em vez de ver centenas de processos em execução na máquina e não ter controle sobre eles.

Em geral, o administrador define em quantos slots uma máquina pode ser dividida e você envia uma tarefa para uma fila e especifica quantos slots a tarefa deseja consumir, o mecanismo da grade monitorará o uso geral do sistema e executará a operação. trabalho de acordo com a política de filas definida por admin. por exemplo. não mais do que x trabalhos podem ser executados ao mesmo tempo, etc. o restante dos trabalhos estará na fila no estado de espera e liberado depois que os trabalhos anteriores forem concluídos.

    
por 09.12.2015 / 21:22
0

Você pode tentar o shell distribuído. Download de: link

    
por 16.12.2015 / 17:55
0

Eu fiz isso em várias ocasiões e, geralmente, apenas rolo meu próprio script para fazer o trabalho com o controle do trabalho. Genericamente, se você tiver os nomes de todos os scripts que deseja executar em um arquivo, a solução se parece:

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

É força bruta, mas eficaz. Além disso, você não precisa de nenhum software extra como paralelismo seja adicionado aos seus sistemas.

Um grande problema é que o comando wait espera que o script mais lento seja concluído, o que pode perder tempo. Eu criei scripts para cuidar dessa situação, mas eles ficam mais complexos como você pode imaginar. Se todos os seus scripts forem executados na mesma quantidade de tempo, isso funciona bem.

Outro problema é que você pode precisar ajustar o MAX_PROCS para determinar o melhor desempenho.

É claro que o número de conexões ssh pode ficar pesado. Nesse caso, basta mover este script para o host remoto e alterar a linha "ssh ..." para executar os scripts diretamente.

    
por 18.12.2015 / 22:55