Paralléliser rsync en utilisant GNU Parallel

J'ai utilisé un script rsync pour synchroniser datatables sur un hôte avec datatables sur un autre hôte. Les données contiennent de nombreux files de petite taille qui consortingbuent à près de 1,2 To.

Pour synchroniser ces files, j'ai utilisé la command rsync comme suit:

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

Le contenu du projet est le suivant:

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

Comme un test, j'ai ramassé deux de ces projets (8,5 Go de données) et j'ai exécuté la command ci-dessus. Être un process séquentiel, il outil 14 minutes 58 secondes pour terminer. Donc, pour 1,2 To de données, cela prendrait plusieurs heures.

Si je pouvais plusieurs process rsync en parallèle (en utilisant & , xargs ou parallel ), cela économiserait mon time.

J'ai essayé avec la command ci-dessous avec le parallel (après cd au directory source) et il a fallu 12 minutes 37 secondes pour exécuter:

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

Cela aurait dû prendre 5 fois less de time, mais ce n'était pas le cas. Je pense, je me trompe quelque part.

Comment puis-je exécuter plusieurs process rsync afin de réduire le time d'exécution?

    Les étapes suivantes ont fait le travail pour moi:

    1. Exécutez le rsync --dry-run premier afin d'get la list des files qui seraient affectés.

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

    1. J'ai alimenté la sortie de cat transfer.log en parallel afin de faire fonctionner 5 rsync en parallèle, comme suit:

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

    Ici, l'option --relative ( lien ) a assuré que la structure de directory des files affectés, à la source et à la destination, rest la même (dans /data/ directory), donc la command doit être exécutée dans le dossier source /data/projects ).

    Personnellement, j'utilise ce simple:

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

    Lequel est seulement utile lorsque vous avez plus que quelques directorys non-presque-vide, autrement vous finirez par avoir presque chaque rsync terminant et le dernier faisant tout le travail seul.

    Une façon éprouvée de faire le rsync parallélisé est: http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Pallallelizing-rsync

    rsync est un excellent outil, mais parfois il ne remplira pas la bande passante disponible. Ceci est souvent un problème lors de la copy de plusieurs gros files sur des connections haut débit.

    Ce qui suit va démarrer un rsync par grand file dans src-dir à dest-dir sur le 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 dirs created may end up with wrong permissions and smaller files are not being 

    transféré. Pour réparer ceux qui exécutent rsync une dernière fois:

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

    Si vous ne parvenez pas à envoyer des données, mais que vous devez les extraire et que les files sont appelés digits.png (par exemple 000000.png), vous pouvez:

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

    Je déconseillerais vivement quiconque d'utiliser la réponse acceptée, une meilleure solution est d'explorer le directory de premier niveau et de lancer un nombre proportionnel d'opérations rync.

    J'ai un grand volume de zfs et ma source était une monture de cifs. Les deux sont liés à 10G, et dans certains benchmarks peuvent saturer le lien. La performance a été évaluée en utilisant zpool iostat 1 .

    Le lecteur source a été monté comme:

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

    En utilisant un seul process rsync :

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

    l'io countur se lit comme suit:

     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 

    Ceci dans les benchmarks synthétiques (disque de cristal), la performance pour l'écriture séquentielle approche 900 MB / s, ce qui signifie que le lien est saturé. 130 Mo / s n'est pas très bon, et la différence entre attendre un week-end et deux semaines.

    Donc, j'ai construit la list des files et j'ai essayé de relancer la synchronisation (j'ai une machine 64 core):

     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 

    et il a eu la même performance!

     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 

    Comme alternative, j'ai simplement exécuté rsync sur les dossiers racine:

     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 

    Cela a réellement stimulé la performance:

     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 

    En conclusion, comme @Sandip Bhattacharya a soulevé, écrire un petit script pour get les directorys et parallèle. Vous pouvez également passer une list de files à rsync. Mais ne créez pas de nouvelles instances pour chaque file.

    Pour les synchronisations multi destinations, j'utilise

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

    Astuce: Toutes les connections ssh sont établies avec des keys publiques dans ~/.ssh/authorized_keys