it-swarm.com.de

Rsync mit gleichzeitigen / gleichzeitigen Dateiübertragungen beschleunigen?

Wir müssen so schnell wie möglich 15TB Von Daten von einem Server auf einen anderen übertragen. Wir verwenden derzeit rsync, aber wir erreichen nur Geschwindigkeiten von etwa 150Mb/s, Wenn unser Netzwerk 900+Mb/s Kann (getestet mit iperf). Ich habe Tests der Festplatten, des Netzwerks usw. durchgeführt und festgestellt, dass rsync nur jeweils eine Datei überträgt, was die Verlangsamung verursacht.

Ich habe ein Skript gefunden, mit dem für jeden Ordner in einem Verzeichnisbaum ein anderes rsync ausgeführt werden kann (mit dem Sie die Anzahl auf x beschränken können), aber ich kann es nicht zum Laufen bringen, es wird immer noch nur ein rsync gleichzeitig ausgeführt.

Ich fand das scripthier (unten kopiert).

Unser Verzeichnisbaum sieht folgendermaßen aus:

/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

Ich möchte also für jedes der Verzeichnisse in/main/files einen Rsync erstellen, beispielsweise bis zu 5 gleichzeitig. In diesem Fall würden also 3 rsyncs für /main/files/1, /main/files/2 Und /main/files/3 Ausgeführt.

Ich habe es so versucht, aber es wird immer nur 1 rsync für den Ordner /main/files/2 Ausgeführt:

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

Das scheint einfacher zu sein:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
35
Manuel Riel

rsync überträgt Dateien so schnell wie möglich über das Netzwerk. Versuchen Sie es beispielsweise, um eine große Datei zu kopieren, die am Ziel überhaupt nicht vorhanden ist. Diese Geschwindigkeit ist die maximale Geschwindigkeit, mit der rsync Daten übertragen kann. Vergleichen Sie es mit der Geschwindigkeit von scp (zum Beispiel). rsync ist bei Raw-Übertragung sogar noch langsamer, wenn die Zieldatei vorhanden ist, da beide Seiten sich gegenseitig darüber unterhalten müssen, welche Teile der Datei geändert werden, dies zahlt sich jedoch aus, indem nicht benötigte Daten identifiziert werden übertragen werden.

Eine einfachere Möglichkeit, rsync parallel auszuführen, ist die Verwendung von parallel . Der folgende Befehl würde bis zu 5 rsyncs gleichzeitig ausführen, wobei jeder ein Verzeichnis kopiert. Beachten Sie, dass der Engpass möglicherweise nicht Ihr Netzwerk ist, aber die Geschwindigkeit Ihrer CPUs und Festplatten sowie das parallele Ausführen von Dingen machen sie nur langsamer und nicht schneller.

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/*
26
Stuart Caie

Sie können xargs verwenden, um mehrere Prozesse gleichzeitig auszuführen. Für Ihren Fall wird es sein:

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

Es gibt eine Reihe von alternativen Werkzeugen und Ansätzen, um dies im Internet zu tun. Beispielsweise:

  • Das NCSA-Blog beschreibt die Verwendung von xargs und find zur Parallelisierung von rsync, ohne dass für die meisten * nix-Systeme eine neue Software installiert werden muss.

  • Und parsync bietet einen funktionsreichen Perl-Wrapper für paralleles Rsync.

10
Bryan P

Ich habe ein python Paket mit dem Namen: parallel_sync entwickelt

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

Hier ist ein Beispielcode, wie man es benutzt:

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)

parallelität ist standardmäßig 10; Sie können es erhöhen:

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)

beachten Sie jedoch, dass für ssh in der Regel standardmäßig MaxSessions auf 10 festgelegt ist. Wenn Sie den Wert über 10 erhöhen möchten, müssen Sie Ihre ssh-Einstellungen ändern.

4
max

Das Einfachste, was ich gefunden habe, ist die Verwendung von Hintergrundjobs in der Shell:

for d in /main/files/*; do
    rsync -a "$d" remote:/main/files/ &
done

Passen Sie auf, dass die Anzahl der Jobs nicht begrenzt wird! Wenn Sie netzwerkgebunden sind, ist dies kein wirkliches Problem, aber wenn Sie auf das Drehen von Rust warten, wird dies die Festplatte zerstören.

Sie könnten hinzufügen

while [ $(jobs | wc -l | xargs) -gt 10 ]; do sleep 1; done

innerhalb der Schleife für eine primitive Form der Jobsteuerung.

0
sba