Parallelisierung von rsync

30

Ich bin gerade umgezogen und habe nach einigem Ausprobieren festgestellt, dass irgendwo zwischen meinem Zuhause und meinem Remote-Server eine Drosselung stattfindet ... aber die Drosselung ist nicht sehr intelligent. Es werden nur einzelne Verbindungen gedrosselt. Wenn ich also eine 1-GB-Datei kopiere, wird sie fröhlich mit 150 kBit / s fortgesetzt. Wenn ich jedoch 10 Kopien initialisiere, erreicht jede von ihnen 150 kBit / s (dh ich erhalte über mehrere Verbindungen eine viel höhere Gesamtbandbreite).

Ich verwende rsync ziemlich oft, um einige große Datensätze von der Arbeit nach Hause zu synchronisieren (zum Glück in Form vieler Dateien). Gibt es eine Möglichkeit, rsync anzuweisen, über mehrere Verbindungen herunterzuladen? Theoretisch sollte es möglich sein, da rsync, soweit ich das beurteilen kann, zunächst einen Durchgang durchführt, um die erforderlichen Änderungen zu ermitteln, und dann die eigentliche Übertragung durchführt. Bonuspunkte, wenn rsync auf magische Weise angewiesen wird, einzelne Dateien in N Teile zu zerlegen und dann wieder zusammenzufügen. Ich glaube, CuteFTP ist eigentlich schlau genug, um das durchzuziehen.

stuyguy
quelle

Antworten:

13

Ich hatte gerade ein ähnliches Problem, als ich mehrere TB von einem NAS auf einen anderen NAS verlagern musste, ohne Sicherungs- / Wiederherstellungsfunktion, die es mir ermöglichte, nur einen Satz dem anderen zuzuführen.

Also habe ich dieses Skript geschrieben, um 1 rsync für jedes Verzeichnis auszuführen, auf das es stößt. Es hängt davon ab, ob Sie die Quellverzeichnisse auflisten können (seien Sie vorsichtig, um ARG 3 zu umgehen), aber ich denke, Sie könnten diese Stufe mit einem nicht rekursiven Rsync einstellen, der nur Dateien und Verzeichnisse auf die entsprechende Ebene kopiert.

Außerdem wird anhand der Anzahl der Prozessoren festgelegt, wie viele rsync-Vorgänge ausgeführt werden sollen. Möglicherweise möchten Sie dies jedoch optimieren.

Die andere denkbare Option ist: Führen Sie eine rsync im --list-only-Modus aus.

Das würde Ihnen alle Dateien geben, die aktualisiert werden müssen. Führen Sie dann 1 rsync für jede Datei in Ihrer Liste aus, wenn Sie xargs verwendet haben, um die Anzahl der Rsyncs zu verwalten, die Sie ausgeführt haben. Dies könnte sehr elegant sein. Eigentlich wohl eine elegantere Lösung als mein kleines Drehbuch hier ...

#! /bin/bash
SRC_DIR=$1
DEST_DIR=$2
LIST=$3
CPU_CNT=`cat /proc/cpuinfo|grep processor |wc -l`
#  pseudo random heuristic
let JOB_CNT=CPU_CNT*4
[ -z "$LIST" ] && LIST="-tPavW --exclude .snapshot --exclude hourly.?"
echo "rsyncing From=$SRC_DIR To=$DEST_DIR DIR_LIST=$LIST"
mkdir -p /{OLD,NEW}_NAS/home
[ -z "$RSYNC_OPTS" ] && RSYNC_OPTS="-tPavW --delete-during --exclude .snapshot --exclude hourly.?"
cd $SRC_DIR
echo $LIST|xargs -n1 echo|xargs -n1 -P $JOB_CNT -I% rsync ${RSYNC_OPTS} ${SRC_DIR}/%/ ${DEST_DIR}/%/
kkron
quelle
2
Dies funktioniert - Sie können viele Verbesserungen an der Funktionsweise vornehmen, aber das Konzept der Verwendung von xargs zur Parallelisierung Ihrer Anwendung ist ziemlich neu.
MattPark
6

GNU Parallel hat eine Lösung

Ich habe 15 TB durch 1 Gbit / s verschoben und es kann die 1 Gbit / s-Verbindung sättigen.

Das Folgende startet eine rsync pro große Datei in src-dir, um auf dem Server fooserver zu dest-dir:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{}

Die erstellten Verzeichnisse haben möglicherweise falsche Berechtigungen und kleinere Dateien werden nicht übertragen. So beheben Sie, dass rsync ein letztes Mal ausgeführt wird:

rsync -Havessh src-dir/ fooserver:/dest-dir/
Ole Tange
quelle
1
Würde es Ihnen etwas ausmachen, den Abschnitt "BEISPIEL: Parallelisierung von rsync" in Ihre Antwort einzufügen? Nur für den Fall, dass der Link in der Zukunft abbricht.
Picobit
3

Ja. Ein solches Merkmal existiert.

Es gibt ein Hilfsprogramm namens pssh , das die beschriebene Funktionalität bereitstellt.

Dieses Paket enthält parallele Versionen der openssh-Tools. In der Distribution enthalten:

  • Paralleles ssh (pssh)
  • Paralleles scp (pscp)
  • Parallele Synchronisierung (Prsync)
  • Parallele Nuke (pnuke)
  • Paralleles Schlürfen (pslurp)

Ich bin mir nicht sicher, wie einfach das Einrichten ist, aber vielleicht reicht es!

Tim Bielawa
quelle
26
Die pssh-Dienstprogramme werden verwendet, um Befehle auf mehrere Server zu verteilen, und nicht, um denselben Befehl mehrmals auf einem Server auszuführen. Insbesondere unterstützt prsync nur das Senden einer Datei auf Ihrem lokalen Computer an mehrere externe Computer. Das Herunterladen einer Remote-Datei mit mehreren Verbindungen wird nicht unterstützt.
Derek Dahmer
1
Angesichts des Kommentars von @ DerekDahmer möchte das Poster dieser Antwort sie möglicherweise zurückziehen?
mc0e
3

Ich kann keinen Kommentar abgeben, daher habe ich eine neue Antwort hinzugefügt, die einen etwas besseren Code enthält als der vorherige (nette und intelligente) Code.

Überprüfen Sie die rsyncZeile, da sie eine optionale ioniceOptimierung enthält .

#!/bin/bash
start_time=$(date +%s.%N)
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=6
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/user/public_html/images
[email protected]:/home/user/public_html/images
RSYNC_OPTS="-ah --partial"
# Main loop:
for FULLDIR in $SRC_BASE/*; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 1
    done
    DIR=`basename $FULLDIR`
    echo "Start: " $DIR
    ionice -c2 -n5 rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    # rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    sleep 5
done

execution_time=$(echo "$(date +%s.%N) - $start" | bc)
printf "Done. Execution time: %.6f seconds\n" $execution_time
Widmo
quelle
2

Es sieht so aus, als hätte jemand dieses Dienstprogramm für Sie geschrieben. Die Übertragung wird in parallele Abschnitte aufgeteilt. Dies ist eine bessere Implementierung als die unter GNU Parallel aufgeführte "Parallel Big File" -Version:

https://gist.github.com/rcoup/5358786

Außerdem kann LFTP Dateiübertragungen über FTP, FTP, HTTP, HTTPS, HFTP, FISH, SFTP parallelisieren. Häufig bietet die Verwendung von LFTP einige Vorteile, da das Verwalten von Berechtigungen, der eingeschränkte Zugriff usw. für rsync eine Herausforderung sein kann.

Erik Aronesty
quelle
Während dies funktioniert, kann es schnell zu einer massiven Fragmentierung der Festplatte kommen, da Sie nicht einfach mehrere Verbindungen verwenden, um dieselbe Datei herunterzuladen.
bparker
1

Nein, es gibt keine solche Funktion. Sie können die Synchronisierung in mehrere Anrufe aufteilen, rsyncwenn Sie dies wirklich möchten.

Ich würde vorschlagen, dass Sie herausfinden, was auch immer diese Geschwindigkeitsbegrenzung bewirkt, und sich ernsthaft mit demjenigen unterhalten, der sie verwaltet.

David Schwartz
quelle
4
Häufig stammen diese Einschränkungen von ISPs wie Comcast. Viel Glück, dass Sie mit ihnen ein vernünftiges Gespräch führen.
James Moore
1

Ich wollte mehrere Verzeichnisse (mit vielen Dateien) gleichzeitig übertragen, also habe ich dieses kleine Skript erstellt:

#!/bin/bash
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=10
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/sites
DST_BASE=user@example.com:/var/www
RSYNC_OPTS="--stats -ilrtpog"
# Main loop:
for FULLDIR in $SRC_BASE/*/; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 10
    done
    DIR=`basename $FULLDIR`
    rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ & 
    sleep 1 
done
echo "Done."

Ich habe dieses Skript sehr schnell erstellt. Bitte überarbeiten und testen Sie es, bevor Sie es in einer Produktionsumgebung verwenden.

Lepe
quelle
0

Ich habe das folgende Skript erstellt, um viele Ordner mit Bildern parallel hochzuladen. Sie führen es zuerst mit dem Synchronisierungsziel und dann mit allen zu kopierenden Ordnernamen aus.

#!/bin/sh

dest="$1"
shift

if [ "$dest" = "" ]; then
    echo "USAGE: $0 TARGET:/foo/bar <dir1> [dir2] [dir3]"
    exit 1
fi

RCol='\x1B[0m' # Text Reset
BYel='\x1B[1;33m';

for i in "$@"; do
    prefix=`printf "$BYel%50s:$RCol" "$i"`
    echo "$prefix * Starting $i"
    echo "$prefix -> syncing '$i/' to '$dest/$i/'"
    (rsync -rv "$i/" "$dest/$i/") 2>&1 | sed "s/^/$prefix /g" &
    sleep 0.5
done

echo "* Waiting for all to complete"
wait

Der Ordnername wird in allen rsync-Konsolenausgaben gelb vorangestellt, damit er hübsch aussieht.

konrad
quelle
-1

Aria2 ist ein gutes Client-Programm zum Herunterladen von Daten über viele Verbindungen von vielen Spiegeln. SFTP wird nicht unterstützt. Also habe ich FTP-Server installiert - vsftpd . Meine 3G-Verbindung funktioniert mit voller Leistung mit 5 Verbindungen zum FTP-Server.

Puchu
quelle
1
Würden Sie darauf näher eingehen, um Ihre Antwort nützlich zu machen?
Tog