2014-06-05 4 views
24

Nous devons transférer 15TB de données d'un serveur à l'autre aussi vite que possible. Nous utilisons actuellement rsync mais nous obtenons seulement des vitesses autour de 150Mb/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 je me suis dit que rsync ne transférait qu'un seul fichier à la fois, ce qui causait le ralentissement.Accélérer rsync avec des transferts de fichiers simultanés/simultanés?

J'ai trouvé un script pour exécuter un rsync différent pour chaque dossier dans une arborescence de répertoires (vous permettant de limiter à x nombre), mais je n'arrive pas à le faire fonctionner, il exécute encore un rsync à la fois.

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

Notre arborescence 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/main/fichiers, jusqu'à un maximum de, disons, 5 à la fois. Donc dans ce cas, 3 rsyncs fonctionnerait, pour /main/files/1, /main/files/2 et /main/files/3.

J'ai essayé avec elle comme ça, mais il fonctionne seulement 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 '[email protected]^\./@@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}/" 

Répondre

20

rsync fichiers transfert 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 au transfert brut lorsque le fichier de destination existe, parce que les deux parties doivent avoir une conversation bidirectionnelle sur les parties du fichier qui sont modifiées, mais les rentabilise en identifiant les données qui n'ont pas besoin d'être transférées.

Une façon plus simple d'exécuter rsync en parallèle serait d'utiliser parallel. La commande ci-dessous peut aller jusqu'à 5 rsync s en parallèle, chacun copiant un répertoire. Sachez que le goulot d'étranglement n'est peut-être pas votre réseau, mais la vitesse de vos processeurs et de vos disques, et le fait de faire fonctionner les choses en parallèle, les rendent tous plus lents, et non plus rapides.

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/* 
+0

Juste essayé ceci et n'a pas pu obtenir ceci pour fonctionner non plus. 'ls -1/main/fichiers/* | xargs -i -n5 rsync -av {}/main/filesTest/{} 'vient de me donner une tonne de telles erreurs de fichier ou de répertoire de rsync. Comment est-ce que je pourrais simplement imprimer la commande rsync au lieu de l'exécuter pour que je puisse voir ce qui ne va pas? – BT643

+0

Vous pouvez le changer de 'rsync' à' echo rsync' –

+0

Ah, désolé, 'xargs' n'est pas correct, il devrait être' parallel'. J'ai mis à jour la réponse. –

27

Cela semble plus simple:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{} 
+4

Notez, si vous personnalisez votre sortie 'ls' par divers moyens, tels que la variable' LISTFLAGS 'ou le fichier' DIR_COLORS', vous devrez peut-être utiliser 'ls --indicator-style = none' pour empêcher' ls' d'être ajouté des symboles au nom du chemin (comme '*' pour les fichiers exécutables). – chadrik

+2

J'ai trouvé que cela fonctionnait beaucoup mieux si j'utilisais cd/sourcedir; parallel -j8 -i rsync -aqH {}/destdir/{} - * – Criggie

7

Il y a un certain nombre d'outils et approches pour ce faire la liste arround le web. Par exemple:

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

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

+2

Veuillez ne pas simplement poster un outil ou une bibliothèque en guise de réponse. Au moins démontrer [comment il résout le problème] (http://meta.stackoverflow.com/a/251605) dans la réponse elle-même. –

+0

@i_m_mahii Stack Exchange devrait conserver automatiquement une copie des pages liées. –

1

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 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) 

noter cependant que ssh a généralement les MaxSessions par jeu par défaut à 10 afin d'augmenter au-delà de 10, vous devrez modifier vos paramètres de ssh.

4

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/ 
Questions connexes