Como copiar três arquivos de uma vez, em vez de um arquivo por vez no bash shell scripting?

1

Estou executando meu script de shell em machineA , que copia os arquivos de machineB e machineC para machineA .

Se o arquivo não estiver em machineB , ele deverá estar em machineC , com certeza. Então, vou tentar copiar o arquivo de machineB primeiro, se não estiver lá em machineB , então irei para machineC para copiar os mesmos arquivos.

Em machineB e machineC , haverá uma pasta como esta YYYYMMDD dentro desta pasta -

/data/pe_t1_snapshot

Então, qualquer data é a data mais recente neste formato YYYYMMDD dentro da pasta acima - eu escolherei essa pasta como o caminho completo de onde eu preciso para começar a copiar os arquivos -

suponha que se esta for a pasta de data mais recente 20140317 inside /data/pe_t1_snapshot , então este será o caminho completo para mim -

/data/pe_t1_snapshot/20140317

de onde preciso começar a copiar os arquivos em machineB e machineC . Eu preciso copiar em torno de 400 arquivos em machineA de machineB e machineC e cada tamanho de arquivo é 2.5 GB .

Anteriormente, eu estava tentando copiar os arquivos um por um em machineA , o que é muito lento. Existe alguma maneira, eu posso copiar "três" arquivos de uma só vez em machineA usando threads no script de shell bash?

Abaixo está meu script de shell que copia o arquivo um por um em machineA de machineB e machineC .

#!/usr/bin/env bash

readonly PRIMARY=/export/home/david/dist/primary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot

PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200

dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)

## Build your list of filenames before the loop. 
for n in "${PRIMARY_PARTITION[@]}"
do
    primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done

if [ "$dir1" = "$dir2" ]
then
    find "$PRIMARY" -mindepth 1 -delete
    rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ 2>/dev/null
    rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ 2>/dev/null
fi  

Então, estou pensando em copiar um arquivo de cada vez, porque não basta copiar "três" arquivos de uma só vez e, assim que esses três arquivos forem concluídos, passarei para outros três arquivos da lista para copiar ao mesmo tempo. ?

Eu tentei abrir três instâncias putty e copiei um arquivo dessas três instâncias ao mesmo tempo. Todos os três arquivos foram copiados em ~ 50 segundos, o que foi rápido para mim. E por esse motivo, estou tentando copiar três arquivos de uma só vez, em vez de um arquivo de cada vez.

Isso é possível? Se sim, então alguém pode fornecer um exemplo sobre isso? Eu só queria dar uma olhada e ver como isso está dando certo.

@terdon me ajudou com a solução acima, mas eu queria tentar copiar três arquivos de uma só vez para ver como ela se comportaria.

Atualização: -

Abaixo está a versão simplificada do script de shell acima. Ele tentará copiar arquivos de machineB e machineC para machineA , pois estou executando o script de shell abaixo em machineA . Ele tentará copiar os números dos arquivos que estão presentes em PRIMARY_PARTITION .

#!/usr/bin/env bash

readonly PRIMARY=/export/home/david/dist/primary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot

PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200

dir1=/data/pe_t1_snapshot/20140414
dir2=/data/pe_t1_snapshot/20140414

## Build your list of filenames before the loop. 
for n in "${PRIMARY_PARTITION[@]}"
do
    primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done

if [ "$dir1" = "$dir2" ]
then
    # delete the files first and then copy it.
    find "$PRIMARY" -mindepth 1 -delete
    rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/
    rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/
fi
    
por arsenal 21.04.2014 / 07:34

2 respostas

1

Fazer várias cópias em paralelo raramente é útil: se o fator limitante é a largura de banda da rede ou a largura de banda do disco, você acabará com N fluxos paralelos, cada um indo para 1 / N vezes a velocidade.

Por outro lado, quando você está copiando de ou para múltiplas fontes (aqui B e C), então há uma vantagem em fazer as cópias em paralelo se o gargalo estiver no lado de B e C (em vez disso do que no lado comum). Então você pode tentar fazer as cópias em paralelo:

rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ &
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ &
wait

Observe que a saída dos dois comandos rsync será mesclada; você pode querer enviá-lo para arquivos separados.

log_base=$(date +%Y%m%d-%H%M%S-$$)
rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ >$log_base-B.log &
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ >$log_base-C.log &
wait

Você está usando várias conexões SSH para o mesmo destino em seu script. Estabelecer uma conexão SSH tem uma latência inevitável. Você pode economizar um pouco de tempo deixando a conexão aberta e reutilizando-a, o que é fácil graças a conexões mestras .

    
por 22.04.2014 / 03:26
0

Você pode fazer várias coisas em paralelo usando processos em segundo plano . Como um exemplo geral:

rsync foo machine1: &
rsync bar machine2: &
rsync baz machine3: &
wait

O wait garante que o programa não progride além desse ponto antes que todos os processos em segundo plano criados pelo script sejam concluídos.

O & fica no final de cada linha de comando, pois como ; é um separador de comando.

    
por 21.04.2014 / 09:38