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é script
ici (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}/"
5 réponses
Cela semble plus simple:
ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
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/*
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/
il existe un certain nombre d'outils et d'approches alternatifs pour faire cela sur le web. Par exemple:
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.