Acelerar o rsync com transferências simultâneas/simultâneas de Ficheiros?
rsync
mas só estamos obtendo velocidades de cerca de 150Mb/s
, Quando nossa rede é capaz de 900+Mb/s
(testado com iperf
). Eu fiz testes dos discos, rede, etc e percebi que é apenas que o rsync está apenas transferindo um arquivo de cada vez que está causando a desaceleração.
encontrei um programa para executar um rsync diferente para cada pasta numa árvore de pastas (o que lhe permite limitar o x number), but I can't get it working, it still runs one rsync at a time.
Encontrei o ...script
aqui (copiado abaixo).
A nossa árvore de directórios é assim:
/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
Então o que eu gostaria de acontecer é criar um rsync para cada um dos diretórios em /main/files, até um máximo de, digamos, 5 de cada vez. Assim, neste caso, 3 rsyncs funcionariam, para /main/files/1
, /main/files/2
e /main/files/3
#!/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 answers
ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
rsync
transfere arquivos o mais rápido possível sobre a rede. Por exemplo, tente usá-lo para copiar um arquivo grande que não existe de todo no destino. Essa velocidade é a velocidade máxima que o rsync pode transferir dados. Compare-o com a velocidade de scp
(por exemplo). rsync
é ainda mais lento na transferência raw quando o ficheiro de destino existe, porque ambos os lados têm de ter uma conversa bidireccional sobre as partes do ficheiro que são alteradas, mas paga por si próprio identificando dados que não precisam de ser transferido.
Uma maneira mais simples de executar rsync
em paralelo seria usar parallel
. O comando abaixo seria executado até 5 rsync
s em paralelo, cada um copiando uma pasta. Esteja ciente de que o gargalo pode não ser a sua rede, mas a velocidade de seus CPUs e discos, e correr as coisas em paralelo apenas os torna todos mais lentos, não mais rápidos.
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/*
Pode usar xargs
que suporta correr muitos processos de cada vez. Para o seu caso será:
ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/
Há uma série de ferramentas e abordagens alternativas para fazer isso listado em toda a web. Por exemplo:
Desenvolvi um pacote python chamado: parallel_sync
Https://pythonhosted.org/parallel_sync/pages/examples.html
Aqui está um código de exemplo como usá-lo:
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)
O paralelismo por omissão é de 10; pode aumentá-lo:
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)
No entanto, note que o ssh normalmente tem as MaxSessions por padrão definidas para 10 de modo a aumentá-lo para além de 10, você terá que modificar a sua configuração do ssh.