Große Datenbestände mit lftp synchronisieren

Im letzten Artikel zum File Transfer Protocol wurde die moderne Einrichtung eines FTP-Servers vorgestellt. Jetzt soll ein Verzeichnis des FTP-Servers mit einem lokalen Server synchronisiert werden.

Besonders der Maximaldurchsatz soll dabei errreicht werden. Dazu bieten viele Windows FTP-Clients zwei Modi an.

  • Segmentiert
    bedeutet, dass eine Datei in logische Abschnitte geteilt und mit mehreren Verbindungen heruntergeladen und auf dem Zielcomputer zusammengesetzt wird.
  • Threaded
    bedeutet mehrere Dateien gleichzeitig über mehrere Datenverbindungen herunterzuladen.

Sowohl Threaded wie auch Segmented Übertragungen sollen gegebenfalls vorhandene Durchsatzprobleme bei Verwendung einer einzigen Verbindung umgehen. Das geht doch auch mit Linux?

Im folgenden wird ein Skript vorgestellt, dass lftp so in einer screen Sitzung startet, dass die Vorteile der Segmented und Threaded Verfahren zusammen mit den Vorteilen einer Hintergrundsitzung bietet. Dabei kommt der FTP-Client lftp zum Einsatz, der sich zur Automatisierung besonders gut eignet, weil er umfangreiche Konfigurationsmöglichkeiten bietet.

lftp Konfigurieren

Zuerst muss die notwendige Software installiert werden.

apt-get install lftp screen

Bevor das Skript eingesetzt werden kann, muss lftp konfiguriert werden, indem im Verzeichnis ~/.lftp/ des ausführenden Benutzers eine Datei rc mit folgendem Inhalt angelegt wird.

# GENERAL
set color:use-color true

# FTP
set ftp:list-options -a
set ftp:passive-mode true
# Send multiple commands async.
set ftp:sync-mode false

# SEGMENTED
set pget:default-n 4
set pget:save-status 30

# DIRECTORES
set mirror:order "*.txt [rR]eadme"
set mirror:use-pget-n 4
set mirror:parallel-transfer-count 2
set mirror:parallel-directories true

# Always SSL!
set ftp:ssl-force true

# Foreground cmds first!
set net:connection-takeover true
# Disconnect after 30mins idle!
set net:idle 1800
# Max 32 connections to everywhere!
set net:connection-limit 32

Synchronisations-Skript

Das folgende Skript synchronisiert das Verzeichnis REMOTE_DIR mit dem Verzeichnis LOCAL_DIR. Dafür wird eine screen Sitzung mit dem Namen lftp-sync im Hintergrund gestartet, in der lftp gestartet wird. An diese Sitzung sendet das Skript den mirror Befehl und beendet sich nach dem sichergestellt ist, dass eine solche Sitzung auch existiert.

#!/bin/bash

# Information about the source
HOST="123.123.123.123"
PORT=21
USER="sync"
PASS="foobar"

# download target
LOCAL_DIR="/mnt/123.123.123.123/forschungsdaten"

# source dir
REMOTE_DIR="/forschungsdaten"

function lftpcmd()
{
screen -S lftp-sync -p 0 -X stuff "$1"`echo -ne '\015'` 2>&1 >> /dev/null
}
function lftpkill()
{
screen -ls lftp-sync | grep lftp-sync | cut -d "." -f 1 | sed -e 's/^[ \t]*//' | xargs kill -9 $1
screen -wipe
}

# Start background lftp session if none or more than 1 is found running
if ! [ "`screen -ls lftp-sync | lftp-sync | wc -l`" -eq 1 ]; then
if [ "`screen -ls lftp-sync | grep lftp-sync | wc -l`" -gt 1 ]; then
lftpkill
fi
# Start a new session
screen -dmS lftp-sync lftp
# Set up the connection using commands sent to screen
lftpcmd "open ftp://$USER:$PASS@$HOST:$PORT/"
fi

# Add a new sync to the queue
lftpcmd "queue mirror -x ^\Incoming/$ -p \"${REMOTE_DIR}\" \"${LOCAL_DIR}\""

9 comments

    1. Danke Kerstin,
      für Fragen und Verbesserungsvorschläge bin ich zwar immer offen, freue mich aber deutlich mehr über Lob :)

      Wenn du Fragen hast, tu dir bitte keinen Zwang an.

      Grüße

  1. Schönes Ding, leider kann ich das nicht verwenden, da die Dateien die ich syncronisieren möchte 60-70 GB haben.
    Hab sie gesplittet und übertrage die in 500MB Teilen, die ich dannach mit md5sum überprüfe, dannach zusammensetzt und die Splits lösche.

    Etwa so:
    [Schauen ob es auf dem ftp nen Ordner gibt, der lokal noch nicht vorhanden ist]
    screen
    mkdir Ordner1
    cd Ordner1
    lftp user.pass@ftp.server.de
    mget /Ordner1/x* split.md5
    exit
    md5sum -c split.md5
    cat x* > Datei
    rm -f x*
    exit

    Ausserdem käme dazu, dass ich nur zwischen 19 und 6 Uhr übertragen kann.
    Jemand nen Denkanstoß parat das Script entsprechend zu erweitern?

    1. Hallo,

      na die erste Frage die sich mir da stellt ist, warum du die Dateien vor der Übertragung per Hand splittest. Genau dafür sind doch die im Beitrag vorgestellten segmentierten Downloads gut. Wichtig ist nur, dass der Client wie auch der Server es unterstützen. Wenn du vsftpd einsetzt ist das kein Problem.

      Damit würdest du dir schonmal den Schritt mit dem Auftrennen sparen.

      Wenn dir Prüfsummen dieser großen Dateien wichtig sind, meld dich nochmal im Kommentar, da lässt sich auch was machen.
      Was das Zeitfenster angeht, das ist eine Leichtigkeit. Du startest das Skript einfach täglich um 19 Uhr mittels cron:

      0 19 * * * /pfad/zu/lftpsync.bash

      Aus dem Skript entnimmst du die Funktion lftpkill() und speicherst sie in einem eigenen Skript. Das lässt du dann um 5:59 Uhr laufen.

      59 5 * * * /pfad/zu/lftpkill

      Grüße

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>