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


16

Posso ssh em uma máquina remota com 64 núcleos. Digamos que eu precise executar 640 scripts de shell em paralelo nesta máquina. Como eu faço isso?

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

Um script do formulário

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

onde script_Acorresponde ao primeiro grupo, script_Bao segundo grupo etc., é suficiente?

Os scripts em um grupo que são executados em um núcleo podem ser executados sequencialmente, mas eu quero que os grupos sejam executados em paralelo em todos os núcleos.


Não é garantido que eles sejam distribuídos uniformemente pelos núcleos. Dê uma olhada neste tópico. stackoverflow.com/questions/13583146/…
Rui F Ribeiro

Respostas:


24

Parece um trabalho para o gnu paralelo:

parallel bash -c ::: script_*

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

Obviamente, se você não quiser cuidar da sessão SSH enquanto os scripts estiverem em execução, use nohupouscreen


É uma boa resposta e aceito-a, pois, no caso geral, isso funcionaria bem. Infelizmente, para mim, pessoalmente, não tenho privilégios de administrador na máquina remota e, portanto, não consigo instalar o parallelpacote. Obrigado`
Tom

10
Você não precisa instalar o paralelo globalmente: deve poder executar uma cópia do seu próprio diretório inicial.
Dg9

bash -cpode ser desnecessário: parallel ::: ./script*. Com o script 640, é provável que eles sejam muito semelhantes (por exemplo, apenas um argumento é diferente). Para isso, considere usar o GNU Parallel diretamente para definir esses argumentos e usar um único script.
quer

Como eu instalaria o gnu paralelo em uma máquina remota?
Tom

@ Tom O que é alterado pelo fato de você estar usando uma máquina remota? Basta obter o pacote certo em gnu.org/software/parallel e instalar.
Dmitry Grigoryev

5

Isso funcionará desde que você não precise monitorar a saída e esteja bem, deixando sua sessão ssh aberta enquanto os scripts demorarem para ser executados. Se um desses não for verdade, eu recomendaria o uso screencom várias guias. Você poderia fazer algo como

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

Monitorando as saídas com as quais não estou preocupado - não gostaria de deixar a sessão ssh aberta. Que tal usar nohup? Isso impediria que os scripts parassem se a sessão terminasse não? Também darei uma olhada na sua recomendação de tela. Obrigado!'
Tom

nohupprovavelmente funcionaria, estou familiarizado com screenisso e tem muito mais funcionalidades que podem ou não ser úteis para você.
David King

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), ver o status da tarefa (aguardar, suspender, executar, concluído).

O mecanismo de grade foi criado para isso, por exemplo, o Sun Grid Engine ( http://wiki.gridengine.info/wiki/index.php/Main_Page ) ou o Open Grid Scheduler ( http://gridscheduler.sourceforge.net/ ). Você precisa do administrador para instalar o software adequado antes de iniciar. O administrador pode fazer isso com prazer, 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 um trabalho para uma fila e especifica quantos slots o trabalho deseja consumir, o mecanismo da grade monitorará o uso geral do sistema e executará o trabalho de acordo com a política de enfileiramento definida pelo administrador. por exemplo, não mais do que x trabalhos podem ser executados ao mesmo tempo, etc. o restante dos trabalhos estará na fila em estado de espera e liberado após o término dos trabalhos anteriores.



0

Eu já fiz isso em várias ocasiões e geralmente apenas rolar meu próprio script para fazer o trabalho com controle de trabalho. Genericamente, se você tiver os nomes de todos os scripts que deseja executar em um arquivo, a solução será semelhante 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

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

Um grande problema é que o comando wait aguardará a conclusão do script mais lento, 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 funcionará bem.

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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.