Paraleliza o rsync usando o GNU Parallel

11

Eu tenho usado um script rsync para sincronizar dados em um host com os dados em outro host. Os dados têm vários arquivos de tamanho pequeno que contribuem com quase 1,2 TB.

Para sincronizar esses arquivos, tenho usado o comando rsync da seguinte forma:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

O conteúdo de proj.lst é o seguinte:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

Como teste, peguei dois desses projetos (8.5GB de dados) e executei o comando acima. Sendo um processo sequencial, a ferramenta 14 minutos e 58 segundos para concluir. Então, para 1,2 TB de dados, levaria várias horas.

Se eu pudesse processar vários rsync em paralelo (usando & , xargs ou parallel ), isso economizaria meu tempo.

Eu tentei com o comando abaixo com parallel (depois de cd ing no diretório fonte) e demorou 12 minutos e 37 segundos para executar:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

Isso deveria ter levado 5 vezes menos tempo, mas isso não aconteceu. Eu acho que estou errado em algum lugar.

Como posso executar vários processos de rsync para reduzir o tempo de execução?

    
por Mandar Shinde 13.03.2015 / 07:51

6 respostas

11

Seguir os passos fez o trabalho para mim:

  1. Execute o rsync --dry-run primeiro para obter a lista de arquivos afetados.

rsync -avzm --stats --safe-links --ignore-existing --dry-run --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log

  1. Eu alimentei a saída de cat transfer.log a parallel para executar 5 rsync s em paralelo, da seguinte maneira:

cat /tmp/transfer.log | parallel --will-cite -j 5 rsync -avzm --relative --stats --safe-links --ignore-existing --human-readable {} REMOTE-HOST:/data/ > result.log

Aqui, --relative opção ( link ) garantiu que a estrutura de diretórios dos arquivos afetados, na origem e no destino, permanecesse a mesma (dentro do diretório /data/ ), portanto, o comando deve ser executado na pasta de origem (no exemplo, /data/projects ).

    
por 11.04.2015 / 15:53
8

Desencorajaria strongmente qualquer pessoa de usar a resposta aceita, uma solução melhor é rastrear o diretório de nível superior e iniciar um número proporcional de operações de rync.

Eu tenho um grande volume de zfs e minha fonte era uma montagem cifs. Ambos estão ligados a 10G e, em alguns benchmarks, podem saturar o link. O desempenho foi avaliado usando zpool iostat 1 .

A unidade de origem foi montada como:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

Usando um único processo rsync :

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

o medidor da io lê:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

Isso em benchmarks sintéticos (disco de cristal), desempenho para abordagens de gravação sequenciais de 900 MB / s, o que significa que o link está saturado. 130MB / s não é muito bom, e a diferença entre esperar um final de semana e duas semanas.

Então, criei a lista de arquivos e tentei executar a sincronização novamente (tenho uma máquina de 64 núcleos):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

e teve o mesmo desempenho!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

Como alternativa, simplesmente executei o rsync nas pastas raiz:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

Isso realmente impulsionou o desempenho:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

Em conclusão, como o @Sandip Bhattacharya criou, escreva um pequeno script para obter os diretórios e faça um paralelo disso. Como alternativa, passe uma lista de arquivos para o rsync. Mas não crie novas instâncias para cada arquivo.

    
por 10.04.2017 / 05:28
6

Eu pessoalmente uso este simples:

ls -1 | parallel rsync -a {} /destination/directory/

Que só é útil quando você tem mais do que alguns diretórios não quase vazios, senão você vai acabar tendo quase todos os rsync terminando e o último fazendo todo o trabalho sozinho.

    
por 25.05.2016 / 16:15
4

Uma maneira testada de fazer o rsync paralelizado é: link

rsync is a great tool, but sometimes it will not fill up the available bandwidth. This is often a problem when copying several big files over high speed connections.

The following will start one rsync per big file in src-dir to dest-dir on the server fooserver:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{} 

The directories created may end up with wrong permissions and smaller files are not being transferred. To fix those run rsync a final time:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 

If you are unable to push data, but need to pull them and the files are called digits.png (e.g. 000000.png) you might be able to do:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/
    
por 13.03.2015 / 08:25
0

Para sincronizações de vários destinos, estou usando

parallel rsync -avi /path/to/source ::: host1: host2: host3:

Dica: Todas as conexões ssh são estabelecidas com chaves públicas em ~/.ssh/authorized_keys

    
por 10.04.2017 / 08:37
0

Eu sempre pesquiso no rsync paralelo, pois sempre esqueço o comando completo, mas nenhuma solução funcionou para mim como eu queria - ele inclui várias etapas ou precisa instalar parallel . Acabei usando este one-liner para sincronizar várias pastas:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 é a quantidade de processos que você deseja gerar - use 0 para ilimitado (obviamente não recomendado).

--bwlimit para evitar o uso de toda a largura de banda.

-I % argumento fornecido por find (diretório encontrado em dir/ )

$(echo dir/%/ host:/dir/%/) - imprime diretórios de origem e destino que são lidos pelo rsync como argumentos. % é substituído por xargs com o nome do diretório encontrado por find .

Vamos supor que eu tenha dois diretórios em /home : dir1 e dir2 . Eu corro find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)' . Então, o comando rsync será executado como dois processos (dois processos porque /home tem dois diretórios) com os seguintes argumentos:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
    
por 22.11.2018 / 16:43