2014-06-05 32 views
24

Abbiamo bisogno di trasferire 15TB di dati da un server all'altro il più velocemente possibile. Attualmente stiamo usando rsync ma stiamo ottenendo solo una velocità di circa 150Mb/s, quando la nostra rete è in grado di 900+Mb/s (testato con iperf). Ho eseguito test sui dischi, sulla rete, ecc. E ho calcolato che solo rsync trasferisce un file alla volta che sta causando il rallentamento.Accelera rsync con trasferimenti simultanei/simultanei di file?

Ho trovato uno script per eseguire un rsync diverso per ogni cartella in un albero di directory (consentendoti di limitare il numero x), ma non riesco a farlo funzionare, esegue comunque solo un rsync alla volta.

Ho trovato il scripthere (copiato di seguito).

Il nostro albero di directory è come questo:

/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 

Quindi quello che vorrei che accada è quello di creare un rsync per ognuna delle directory in/main/file, fino ad un massimo di, diciamo, 5 alla volta. Quindi, in questo caso, sarebbero eseguiti 3 rsyncs, per /main/files/1, /main/files/2 e /main/files/3.

Ho provato con esso in questo modo, ma semplicemente corre 1 rsync alla volta per la cartella /main/files/2: file come velocemente possibile attraverso la rete

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

risposta

20

rsync trasferimenti. Ad esempio, prova a utilizzarlo per copiare un file di grandi dimensioni che non esiste affatto sulla destinazione. Quella velocità è la velocità massima che rsync può trasferire dati. Confrontalo con la velocità di scp (per esempio). rsync è ancora più lento con il trasferimento non elaborato quando il file di destinazione esiste, perché entrambe le parti devono avere una chat bidirezionale su quali parti del file vengono cambiate, ma si ripaga da solo identificando i dati che non devono essere trasferiti.

Un modo più semplice per eseguire rsync in parallelo sarebbe quella di utilizzare parallel. Il comando seguente potrebbe eseguire fino a 5 rsync s in parallelo, ognuno dei quali copia una directory. Tieni presente che il collo di bottiglia potrebbe non essere la tua rete, ma la velocità delle tue CPU e dei dischi e l'esecuzione in parallelo delle cose li rende tutti più lenti, non più veloci.

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

Ho appena provato questo e non ho potuto farlo funzionare. 'ls -1/main/files/* | xargs -i -n5 rsync -av {}/main/filesTest/{} 'mi ha dato un sacco di errori di file o directory da rsync. Come faccio a stampare il comando rsync invece di eseguirlo in modo da poter vedere cosa sta andando storto? – BT643

+0

Puoi cambiarlo da 'rsync' a' echo rsync' –

+0

Ah, mi dispiace, 'xargs' non è corretto, dovrebbe essere' parallelo'. Ho aggiornato la risposta. –

27

Questo sembra semplice:

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

Nota, se si personalizza l'output 'ls' attraverso vari mezzi, come la variabile' LISTFLAGS 'o il file' DIR_COLORS', potrebbe essere necessario usare 'ls --indicator-style = none' per impedire' ls' di accodare simboli al nome del percorso (come '*' per i file eseguibili). – chadrik

+2

Ho trovato che questo ha funzionato molto meglio se ho usato cd/sourcedir; parallel -j8 -i rsync -aqH {}/destdir/{} - * – Criggie

7

ci sono una serie di strumenti alternativi e approcci per fare questo elencato arround il web. Ad esempio:

  • Il NCSA Blog ha una descrizione dell'utilizzo xargs e find per parallelizzare rsync senza dover installare alcun nuovo software per la maggior parte dei sistemi * nix.

  • E parsync fornisce un ricco wrapper Perl per rync parallelo.

+2

Si prega di non inserire solo alcuni strumenti o librerie come risposta. Dimostrare almeno [come risolve il problema] (http://meta.stackoverflow.com/a/251605) nella risposta stessa. –

+0

@i_m_mahii Stack Exchange dovrebbe conservare automaticamente una copia delle pagine collegate. –

1

ho sviluppato un pacchetto python chiamato: parallel_sync

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

Ecco un codice di esempio come usarlo:

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) 

parallelismo di default è 10; è possibile aumentare:

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) 

tuttavia notare che ssh ha in genere i MAXSESSIONS impostazione predefinita per 10 in modo da aumentare al di là 10, dovrete modificare le impostazioni ssh.

4

È possibile utilizzare xargs che supporta l'esecuzione di molti processi alla volta. Per il tuo caso sarà:

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