Paralelização do tar remoto e obtenção de saída pelo pipe ssh

1

Eu tentei paralelizar o script que estou usando, mas até agora o GNU Parallel é muito desafiador.

Eu tenho 2 arquivos - um contendo hosts nos quais executar o comando e segundo tendo params para o comando. Abaixo estão os dados da amostra:

$ cat workers.host 
[email protected]
[email protected]
[email protected]
[email protected]



$ cat paths
/usr/local/jar/x/y/ jarxy
/usr/local/jar/z/y/ jarzy
/usr/local/jar/y/y/ jaryy
/usr/local/far/x/y/ farxy
/usr/local/jaz/z/z/ jazzz
/usr/local/mu/txt/ana/ acc01
/usr/local/jbr/x/y/ accxy

E para processar isso, eu uso o seguinte script:

#!/bin/bash

echo "Run this on 192.168.130.10";

DATA='date +%F'
DDAY='date +%u'
DOMBAC='nice tar cpzf'

readarray -t hosts < workers.host

len=${#hosts[@]};
processed=0;

while read -r -a line; do

  let hostnum=processed%len;

  ssh ${hosts[$hostnum]} -i /root/.ssh/id_rsa "$DOMBAC - ${line[0]}" > "/data/backup/$DDAY/${line[1]}_${DATA}_FULL.tgz"

  let processed+=1;
done < paths

Isso funciona bem, no entanto, processa passo a passo em máquina após máquina. Os hosts são bastante sobrecarregados e a rede não é um problema aqui, então eu queria paralelizar isso o máximo possível. Por exemplo, execute 4 instâncias do comando tar em cada saída do host e do canal por meio do ssh no arquivo denominado corretamente. Estou completamente perdido com o paralelo --results --sshloginfile ... E o que eu finalmente tento realizar é ter 4 jobs em execução em cada host, todos e cada um com parâmetros diferentes (para que, por exemplo, o host 2 não sobrescreva o host 1 já fez). Isso pode ser feito no GNU Parallel?

    
por Johnny_Bit 21.01.2017 / 16:16

2 respostas

1

Primeiro, você precisa saber como extrair vários argumentos de uma única linha de entrada:

cat paths | parallel --colsep ' ' echo {2} == {1}

(Eu noto que alguns dos {2} podem ser gerados a partir de {1}. Se esse é sempre o caso, você pode querer olhar para {= =}; mas isso é uma história para outra pergunta). / p>

Para executar trabalhos remotamente, use -S :

cat paths | parallel --colsep ' ' -S server echo {2} == {1}

Para controlar quantos trabalhos são executados em um servidor remoto, use -j :

cat paths | parallel --colsep ' ' -j4 -S server echo {2} == {1}

Para obter a saída armazenada localmente --return --cleanup pode ser usado:

cat paths | parallel --return {2} --cleanup --colsep ' ' -j4 -S server echo {2} == {1} '>' {2}

Como você deseja que a saída seja armazenada em um diretório diferente localmente, você precisará usar o truque /./:

cat paths | parallel --return my/local/dir/./{2} --cleanup --colsep ' ' -j4 -S server echo {2} == {1} '>' {2}

Para usar um comando especial ssh use --ssh :

parallel --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return {2} --cleanup --colsep ' ' -j4 -S server echo {2} == {1} '>' {2}

Para ser executado em vários servidores, use --slf em vez de -S :

parallel --slf hosts.txt --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return {2} --cleanup --colsep ' ' -j4 echo {2} == {1} '>' {2}

Então, no total, seu comando pode ser assim:

parallel --slf hosts.txt --ssh "ssh -i $HOME/.ssh/id_rsa.pub -lroot" --return /data/backup/$DDAY/./{2}_${DATA}_FULL.tgz --cleanup --colsep ' ' -j4 "$DOMBAC - {1} > {2}_${DATA}_FULL.tgz"
    
por 24.01.2017 / 09:15
0

Você pode usar paralelamente para conseguir isso, mas acho que seria um exagero para o que você está tentando realizar. Em vez disso, eu simplesmente usaria trabalhos em segundo plano para executar esses comandos (perto de) simultaneamente.

Para conseguir isso com um mínimo de alterações no seu script existente, tudo o que precisamos fazer é trabalhar com cada tarefa em segundo plano (usando o operador & para fazer isso). Para evitar processos órfãos, devemos garantir que o script não saia até que todas as tarefas tenham terminado, o que é realizado com o bash builtin wait . O comando jobs emitirá uma lista de tarefas em execução (podem não ser todas, algumas podem ter terminado antes de você atingir o ponto dependendo do tempo de execução).

Também não sei ao certo por que você está usando o comando nice sem um argumento - acredito que sem um argumento, tudo o que ele fará será imprimir a prioridade relativa da tarefa iniciada, que, suponho, poderia ser sua intenção.

Aqui está uma versão modificada do seu script com essas alterações

#!/bin/bash

echo "Run this on 192.168.130.10";

DATA='date +%F'
DDAY='date +%u'
DOMBAC='nice tar cpzf'

readarray -t hosts < workers.host

len=${#hosts[@]};
processed=0;

while read -r -a line; do

  let hostnum=processed%len;

  ssh ${hosts[$hostnum]} -i /root/.ssh/id_rsa "$DOMBAC - ${line[0]}" > "/data/backup/$DDAY/${line[1]}_${DATA}_FULL.tgz" &

  let processed+=1;
done < paths
jobs
wait
    
por 22.01.2017 / 19:24