Acelerar o rsync com transferências simultâneas/simultâneas de Ficheiros?

Precisamos transferir dados de um servidor para outro o mais rápido possível. Atualmente estamos usando 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

Tentei assim, mas só funciona 1 rsync de cada vez para o ... pasta:

#!/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}/"
Author: BT643, 2014-06-05

5 answers

Isto parece mais simples.
ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
 29
Author: Manuel Riel, 2014-08-27 16:08:34

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/*
 22
Author: Stuart Caie, 2014-06-05 13:41:50

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/
 8
Author: Nickolay, 2017-10-06 17:38:17

Há uma série de ferramentas e abordagens alternativas para fazer isso listado em toda a web. Por exemplo:

  • O blog NCSA tem uma descrição de usar xargs e find para paralelizar o rsync sem ter de instalar qualquer novo software para a maioria dos sistemas *nix.

  • And parsync provides a feature rich Perl wrapper for parallel rsync.

 7
Author: Bryan P, 2018-10-04 15:21:56

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.

 2
Author: max, 2017-08-01 05:16:14