Accélérer rsync avec des transferts de fichiers simultanés/simultanés?

Nous avons besoin de transférer 15TB de données d'un serveur à l'autre aussi vite que nous le pouvons. Nous utilisons actuellement rsync mais nous n'obtenons que des vitesses d'environ150Mb/s, quand notre réseau est capable de 900+Mb/s (testé avec iperf). J'ai fait des tests sur les disques, le réseau, etc. et j'ai pensé que c'est juste que rsync ne transfère qu'un fichier à la fois ce qui cause le ralentissement.

j'ai trouvé un script pour exécuter un rsync différent pour chaque dossier dans une arborescence de répertoires (vous permettant pour limiter à X nombre), mais je ne peux pas le faire fonctionner, il fonctionne toujours un rsync à la fois.

j'ai trouvé scriptici (copié ci-dessous).

notre arborescence des répertoires est comme ceci:

/main
   - /files
      - /1
         - 343
            - 123.wav
            - 76.wav
         - 772
            - 122.wav
         - 55
            - 555.wav
            - 324.wav
            - 1209.wav
         - 43
            - 999.wav
            - 111.wav
            - 222.wav
      - /2
         - 346
            - 9993.wav
         - 4242
            - 827.wav
      - /3
         - 2545
            - 76.wav
            - 199.wav
            - 183.wav
         - 23
            - 33.wav
            - 876.wav
         - 4256
            - 998.wav
            - 1665.wav
            - 332.wav
            - 112.wav
            - 5584.wav

Donc ce que je voudrais arriver est de créer un rsync pour chacun des répertoires dans /main/fichiers, jusqu'à un maximum de, disons, 5 à la fois. Donc dans ce cas, 3 rsyncs, pour /main/files/1,/main/files/2 et /main/files/3.

j'ai essayé avec ça ceci, mais il fonctionne juste 1 rsync à la fois pour le /main/files/2 dossier:

#!/bin/bash

# Define source, target, maxdepth and cd to source
source="/main/files"
target="/main/filesTest"
depth=1
cd "${source}"

# Set the maximum number of concurrent rsync threads
maxthreads=5
# How long to wait before checking the number of rsync threads again
sleeptime=5

# Find all folders in the source directory within the maxdepth level
find . -maxdepth ${depth} -type d | while read dir
do
    # Make sure to ignore the parent folder
    if [ `echo "${dir}" | awk -F'/' '{print NF}'` -gt ${depth} ]
    then
        # Strip leading dot slash
        subfolder=$(echo "${dir}" | sed 's@^./@@g')
        if [ ! -d "${target}/${subfolder}" ]
        then
            # Create destination folder and set ownership and permissions to match source
            mkdir -p "${target}/${subfolder}"
            chown --reference="${source}/${subfolder}" "${target}/${subfolder}"
            chmod --reference="${source}/${subfolder}" "${target}/${subfolder}"
        fi
        # Make sure the number of rsync threads running is below the threshold
        while [ `ps -ef | grep -c [r]sync` -gt ${maxthreads} ]
        do
            echo "Sleeping ${sleeptime} seconds"
            sleep ${sleeptime}
        done
        # Run rsync in background for the current subfolder and move one to the next one
        nohup rsync -a "${source}/${subfolder}/" "${target}/${subfolder}/" </dev/null >/dev/null 2>&1 &
    fi
done

# Find all files above the maxdepth level and rsync them as well
find . -maxdepth ${depth} -type f -print0 | rsync -a --files-from=- --from0 ./ "${target}/"
31
demandé sur BT643 2014-06-05 15:05:05

5 réponses

Cela semble plus simple:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
29
répondu Manuel Riel 2014-08-27 16:08:34

rsync transfère des fichiers aussi vite que possible sur le réseau. Par exemple, essayez de l'utiliser pour copier un gros fichier qui n'existe pas du tout sur la destination. Cette vitesse est la vitesse maximale rsync peut transférer des données. Comparer avec la vitesse de scp (par exemple). rsync est encore plus lent lors du transfert brut lorsque le fichier de destination existe, parce que les deux côtés doivent avoir une conversation bidirectionnelle sur les parties du fichier qui sont modifiées, mais paie pour lui-même en identifiant les données qui n'ont pas besoin de être transféré.

une façon plus simple de courir rsync en parallèle serait d'utiliser parallel. La commande ci-dessous irait jusqu'à 5 rsync s en parallèle, chacun copiant un répertoire. Soyez conscient que le goulot d'étranglement pourrait ne pas être votre réseau, mais la vitesse de vos CPU et disques, et exécuter les choses en parallèle les rend juste plus lents, pas plus rapides.

run_rsync() {
    # e.g. copies /main/files/blah to /main/filesTest/blah
    rsync -av "" "/main/filesTest/${1#/main/files/}"
}
export -f run_rsync
parallel -j5 run_rsync ::: /main/files/*
22
répondu Stuart Caie 2014-06-05 13:41:50

Vous pouvez utiliser xargs qui supporte l'exécution de nombreux processus à la fois. Pour votre cas, ce sera:

ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/
8
répondu Nickolay 2017-10-06 17:38:17

il existe un certain nombre d'outils et d'approches alternatifs pour faire cela sur le web. Par exemple:

  • NCSA Blog a une description de l'utilisation de xargs et find pour paralléliser rsync sans avoir à installer un nouveau logiciel pour la plupart des systèmes * nix.

  • Et parsync fournit un enveloppeur Perl riche en fonctionnalités pour rsync parallèle.

7
répondu Bryan P 2018-10-04 15:21:56

j'ai développé un paquet python appelé: parallel_sync

https://pythonhosted.org/parallel_sync/pages/examples.html

Voici un exemple de code comment l'utiliser:

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds)

parallélisme par défaut est de 10; vous pouvez l'augmenter:

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds, parallelism=20)

notez cependant que SSH a typiquement les MaxSessions par défaut définies à 10, donc pour l'augmenter au-delà de 10, vous devrez modifier vos paramètres ssh.

2
répondu max 2017-08-01 05:16:14