web-dev-qa-db-fra.com

Accélérer la synchronisation avec les transferts de fichiers simultanés / simultanés?

Nous devons transférer 15TB Des données d'un serveur à un autre aussi rapidement que possible. Nous utilisons actuellement rsync mais nous n'obtenons qu'une vitesse d'environ 150Mb/s, Lorsque 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 je me suis dit que rsync ne transfère qu'un fichier à la fois, ce qui provoque le ralentissement.

J'ai trouvé un script pour exécuter un rsync différent pour chaque dossier dans une arborescence de répertoires (ce qui vous permet de limiter à x nombre), mais je ne parviens pas à le faire fonctionner, il ne lance toujours qu'un rsync à la fois.

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

Notre arborescence de répertoires ressemble à 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 j'aimerais, c’est créer un rsync pour chacun des répertoires dans/main/files, jusqu’à un maximum de 5 à la fois. Donc, dans ce cas, 3 rsyncs seraient exécutés, pour /main/files/1, /main/files/2 Et /main/files/3.

J'ai essayé avec ça comme ça, mais ça ne marche que 1 rsync à la fois pour le dossier /main/files/2:

#!/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}/"
41
BT643

Cela semble plus simple:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
35
Manuel Riel

rsync transfère les fichiers aussi vite que possible sur le réseau. Par exemple, essayez de l'utiliser pour copier un fichier volumineux qui n'existe pas du tout sur la destination. Cette vitesse est la vitesse maximale que rsync peut transférer des données. Comparez-le avec la vitesse de scp (par exemple). rsync est encore plus lent lors du transfert brut lorsque le fichier de destination existe, car les deux parties doivent avoir une conversation à double sens sur les parties du fichier qui ont été modifiées, mais se rentabilisent en identifiant les données inutiles. être transféré.

Une méthode plus simple pour exécuter rsync en parallèle consisterait à utiliser parallel . La commande ci-dessous pourrait exécuter jusqu'à 5 rsyncs en parallèle, chacun copiant un répertoire. Sachez que le goulot d’étranglement n’est peut-être pas lié à votre réseau, mais que la vitesse de vos processeurs et de vos disques, ainsi que l’exécution de tâches en parallèle, les ralentissent, pas plus rapidement.

run_rsync() {
    # e.g. copies /main/files/blah to /main/filesTest/blah
    rsync -av "$1" "/main/filesTest/${1#/main/files/}"
}
export -f run_rsync
parallel -j5 run_rsync ::: /main/files/*
26
Stuart Caie

Vous pouvez utiliser xargs qui prend en charge l'exécution de plusieurs processus à la fois. Pour votre cas ce sera:

ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/
12
Nickolay

Il existe un certain nombre d’outils et d’approches alternatives pour le faire énumérés sur le Web. Par exemple:

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

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

10
Bryan P

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

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

Voici un exemple de code pour 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)

le parallélisme par défaut est 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)

toutefois, notez que ssh a généralement la valeur 10 pour MaxSessions par défaut. Par conséquent, pour l'augmenter au-delà de 10, vous devrez modifier vos paramètres ssh.

4
max

Le plus simple que j'ai trouvé consiste à utiliser des tâches en arrière-plan dans le shell:

for d in /main/files/*; do
    rsync -a "$d" remote:/main/files/ &
done

Attention, cela ne limite pas le nombre d'emplois! Si vous êtes lié au réseau, ce n'est pas vraiment un problème, mais si vous attendez pour tourner Rust), cela écrasera le disque.

Tu pourrais ajouter

while [ $(jobs | wc -l | xargs) -gt 10 ]; do sleep 1; done

dans la boucle pour une forme primitive de contrôle des travaux.

0
sba