Rsync File Synchronization Backup: Deep Dive in Delta-Encoding und Enterprise-Deployment
Rsync ist das unentbehrliche Tool für effiziente, bandbreitenoptimierte Dateiübertragung und inkrementelle Backups. Dieser Artikel taucht tief in das Rolling Checksum-Protokoll ein, beleuchtet Enterprise-Deployment-Strategien und die Erstellung von Snapshots via Hardlinks.
# Rsync – Der Algorithmus für effiziente Datenreplikation
TL;DR / Management Summary Rsync ist weit mehr als ein schneller Kopiervorgang; es nutzt einen proprietären Delta-Encoding-Algorithmus (Rolling Checksum) zur Identifizierung und Übertragung nur der geänderten Blöcke innerhalb von Dateien. Nutzen Sie Rsync immer, wenn Bandbreite, Latenz oder Übertragungsgeschwindigkeit kritisch sind. In Verbindung mit der Option
--link-destist es die Basis für extrem speichereffiziente, rotierende Backup-Systeme auf Dateiebene.
# 1. Einführung & Architektur
In der Praxis ist es oft notwendig, Hunderte von Gigabytes oder Terabytes über WAN-Verbindungen zu synchronisieren, wobei sich nur wenige Megabytes geändert haben. Standardtools versagen hier, da sie die gesamte Datei kopieren würden.
# Warum brauchen wir Rsync?
- Problemstellung aus der Praxis: Bei einem 10 GB großen Datenbank-Dump, bei dem sich lediglich 10 Zeilen geändert haben, müsste
scpdie gesamten 10 GB übertragen. - Rsyncs Lösung (Delta Transfer): Rsync identifiziert die 10 geänderten Blöcke und überträgt nur diese Blöcke, was Bandbreite und Zeit um Größenordnungen reduziert.
- Vergleich mit Alternativen:
- vs.
cp/scp/tar: Rsync ist intelligent; Alternativen sind blind (übertragen immer alles oder nutzen nur Zeitstempel). - vs. ZFS/Btrfs Send/Receive: Dateisystem-basierte Tools sind effizienter auf Blockebene, aber erfordern identische Dateisysteme auf beiden Seiten. Rsync arbeitet auf der Applikationsschicht und ist plattformunabhängig.
- vs.
# Architektur-Diagramm: Das Rolling Checksum Protokoll
Der Kern von Rsync liegt in seinem Algorithmus, der eine Kombination aus einem schnellen Adler-32 Rolling Checksum (schwach) und einem kryptografisch stärkeren Checksum (MD5 oder SHA-1) nutzt.
# Der Übertragungsprozess (6 Phasen)
- Blockifizierung: Die Zieldatei (Receiver/Backup-Ziel) wird in Blöcke fester Größe zerlegt (standardmäßig 700 Bytes, kann variieren).
- Checksummen-Berechnung (Receiver): Für jeden Block berechnet der Empfänger den schnellen Adler-32 und den langsameren, starken Checksum. Diese Liste wird an den Sender geschickt.
- Rolling Checksum (Sender): Der Sender (Source/Quellsystem) liest die Quelldatei. Er nutzt den Adler-32-Algorithmus, um die Checksumme für jeden möglichen Block zu berechnen (sliding window).
- Treffer-Erkennung: Wenn der Sender eine schwache Checksumme findet, die in der Liste des Empfängers enthalten ist, wird die starke Checksumme berechnet und zum Abgleich geschickt.
- Delta-Berechnung: Bei einem starken Checksummen-Mismatch wird der Block als Delta identifiziert. Bei einem Match wird der Block als Match markiert. Die Deltas (die geänderten Blöcke und Anweisungen zur Rekonstruktion) werden gesammelt.
- Übertragung & Rekonstruktion: Der Sender überträgt das kompakte Delta-Set. Der Empfänger nutzt diese Anweisungen und seine vorhandenen lokalen Blöcke, um die neue Datei zu rekonstruieren.
graph TD
A[Sender: Quellsystem] -->|Liste der Checksummen| B(Receiver: Backup-Ziel);
B --> C{Split File & Calculate Checksums (Adler-32 & Strong)};
C --> A;
A --> D[Sender: Rolling Checksum & Match Detection];
D --> E{Identify Matches & Deltas};
E --> |Übertrage kompaktes Delta-Set| B;
B --> F[Receiver: Rekonstruiere die Datei];
# Kernel-Sicht
Rsync ist ein reiner Userspace-Prozess. Es interagiert direkt mit der Dateisystemschicht über Standard-POSIX-Systemaufrufe (read/write) und nutzt Sockets (via SSH oder rsyncd) für die Netzwerkkommunikation. Die Effizienz wird nicht durch den Kernel gesteuert, sondern durch die mathematische Effizienz des Checksum-Algorithmus und die Reduzierung der I/O-Operationen am Zielsystem.
# 2. Installation & Grundkonfiguration (Praxis)
Wir gehen hier primär vom sichersten und flexibelsten Ansatz aus: Rsync über SSH.
# Voraussetzungen
rsyncPaket auf beiden Systemen (Quell- und Zielsystem).- Gute Netzwerkverbindung (WAN oder LAN).
- SSH-Zugriff mit Key-Authentifizierung ohne Passwort.
# Der “Happy Path” für Produktion: Sicher und Inkrementell
Der wichtigste Parameter ist --archive (-a), der die folgenden wichtigen Optionen zusammenfasst: -rlptgoD (Rekursiv, Hardlinks beibehalten, Berechtigungen beibehalten, Zeitstempel beibehalten, Gruppen/Owner beibehalten, Device Files/Specials kopieren).
# Vorbereitung: SSH-Key-Authentifizierung
# Stellen Sie sicher, dass der Backup-User (z.B. 'rsync_user')
# auf dem Zielsystem den SSH-Key des Quellsystems akzeptiert.
SOURCE_DIR="/srv/production_data/"
DESTINATION_HOST="backup-server-01"
DESTINATION_PATH="/mnt/backups/prod-daily/"
USER="rsync_user"
# Rsync-Befehl für vollständige Archivierung und inkrementelle Löschung
# Wichtig: Wir nutzen 'sudo' nur, wenn wir Systemdaten synchronisieren,
# um sicherzustellen, dass Rsync die korrekten Permissions erhält.
# Achtung: Trailing Slash in SOURCE_DIR!
# /srv/production_data/ (mit Slash) kopiert den *Inhalt* von production_data
# /srv/production_data (ohne Slash) kopiert das *Verzeichnis* production_data
# auf das Ziel. Wir wollen in der Regel den INHALT.
rsync -avz --delete \
--progress \
--stats \
--exclude 'cache/' \
--exclude 'temp/*' \
${SOURCE_DIR} \
${USER}@${DESTINATION_HOST}:${DESTINATION_PATH}
# Parameter-Erklärung:
# -a: Archiv-Modus (behält alles bei)
# -v: Verbose (für Log-Analyse)
# -z: Komprimierung (sinnvoll bei WAN, bei LAN/schnellen Links oft Overhead)
# --delete: Löscht Dateien im Ziel, die in der Quelle nicht mehr existieren.
# (Vorsicht! Macht das Ziel zu einem Spiegelbild der Quelle.)
# --progress: Zeigt den Fortschritt an (gut für interaktive Läufe)
# --stats: Liefert am Ende eine Zusammenfassung der Übertragung.
# 3. Deep Dive: Konfiguration für Profis
# Performance Tuning
Obwohl Rsync CPU-intensiv ist (wegen der Checksummen), liegt der Engpass oft bei der I/O- oder Netzwerkleistung.
# I/O- und Prozesspriorität
Wenn Rsync auf einem produktiven System läuft, sollte es die I/O- und CPU-Priorität senken, um die Latenz der primären Applikation nicht zu beeinträchtigen.
# Führe Rsync mit reduzierter Priorität aus:
nice -n 10 ionice -c 3 rsync -a ...
# nice -n 10: Reduziert CPU-Priorität (10 ist niedriger als 0)
# ionice -c 3: Idle I/O Scheduling Class (nutzt nur freie I/O-Zyklen)
# Netzwerk-Optimierung
- Bandbreitenlimitierung:
--bwlimit=KILOBYTES_PER_SECOND. Essentiell auf WAN-Verbindungen, um die Leitung nicht zu überlasten. Beispiel:--bwlimit=2000(2 MB/s). - Checksummen-Überprüfung: Der Standard-Modus (
-a) nutzt Zeitstempel und Größe. Wenn Sie absolute Integrität (z.B. nach einem Festplatten-Crash) benötigen, nutzen Sie--checksum(-c). Dies zwingt Rsync, die Blöcke immer via starker Checksumme zu vergleichen, ist aber dramatisch langsamer.
# --inplace (Extreme Vorsicht!)
Diese Option schreibt geänderte Blöcke direkt in die Zieldatei anstatt eine temporäre Datei zu erstellen.
- Vorteil: Reduziert Platten-I/O und Fragmentation.
- Nachteil: Wenn der Rsync-Prozess abbricht (Stromausfall, Netzwerkfehler), bleibt die Zieldatei in einem inkonsistenten Zustand zurück. Niemals für kritische Produktionsdaten verwenden.
# Hardening & Security
# Restriktionen im SSH-Key
Der rsync_user auf dem Zielsystem sollte nur Rsync-Befehle ausführen dürfen. Dies verhindert, dass ein kompromittiertes Quellsystem Shell-Zugriff erhält.
In der ~/.ssh/authorized_keys auf dem Backup-Ziel:
command="rsync --server --sender -vlogDtprze.iLs --",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3Nz...
Die command Option erzwingt die Ausführung eines spezifischen Rsync-Servers auf dem Ziel, wodurch Shell-Zugriff unterbunden wird.
# Snapshot-Backups mit Hardlinks (--link-dest)
Dies ist die eleganteste Methode für rotierende, inkrementelle Backups. Rsync nutzt Hardlinks, um unveränderte Dateien zwischen Backup-Verzeichnissen zu teilen. Nur die geänderten Dateien belegen neuen Speicherplatz.
# Beispiel: Tägliches Backup mit Rotation
# 1. Erstelle einen Symlink zum letzten erfolgreichen Backup
LATEST_LINK="/mnt/backups/prod-latest"
TODAY_DIR="/mnt/backups/$(date +%Y-%m-%d_%H%M%S)"
# 2. Backup-Verzeichnis erstellen
mkdir -p ${TODAY_DIR}
# 3. Ausführen des Rsync-Befehls
rsync -a \
--link-dest=${LATEST_LINK} \
${SOURCE_DIR} \
${TODAY_DIR}
# 4. Nach erfolgreicher Übertragung (Exit Code 0):
rm -f ${LATEST_LINK}
ln -s ${TODAY_DIR} ${LATEST_LINK}
# Ergebnis: Jedes Backup sieht aus wie ein vollständiges Verzeichnis,
# belegt aber nur Speicher für die Deltas seit dem letzten Lauf.
# 4. Day-2 Operations: Wartung & Alltag
# Typische Tasks
# 1. Dry Run (Testlauf)
Immer verwenden, wenn --delete oder Pfadänderungen involviert sind.
# Simuliert den gesamten Kopiervorgang, führt aber keine Änderungen aus
rsync -avn --delete SOURCE/ USER@HOST:DESTINATION/
# -n oder --dry-run
# 2. Migrieren auf neue Hardware (pvmove analog)
Wenn das Ziel-Speicherarray gewechselt werden muss, können Sie Rsync nutzen, um die Daten online zu migrieren. Da Rsync die Dateien blockweise vergleicht, können Sie einen ersten vollen Sync starten und diesen dann inkrementell wiederholen, bis zur finalen Cut-Over.
- Sync 1 (Vollständig):
rsync -a SOURCE/ NEW_HOST:NEW_PATH/ - Sync 2, 3, 4 (Deltas): Wiederholung des Befehls. Sehr schnell, da nur die Änderungen seit dem letzten Lauf übertragen werden.
- Cut-Over: Anhalten der Anwendung auf dem Quellsystem, letzter Rsync-Lauf, DNS/Mountpoints auf das neue Ziel umstellen.
# Automatisierung (Ansible)
Ein idempotentes Ansible Playbook sollte nicht den eigentlichen Rsync-Lauf steuern (das sollte der Ziel-Cronjob/Systemd-Timer tun), sondern die Vorbereitung der Umgebung.
# Ansible Playbook zur Vorbereitung des Backup-Ziels
---
- name: Setup Rsync Backup Destination
hosts: backup_target_server
vars:
backup_user: rsync_user
backup_root: /mnt/backups
project_name: production_web
tasks:
- name: Ensure rsync_user exists
ansible.builtin.user:
name: "{{ backup_user }}"
state: present
- name: Ensure backup root directory exists
ansible.builtin.file:
path: "{{ backup_root }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Ensure target directory for project exists and is owned by rsync_user
ansible.builtin.file:
path: "{{ backup_root }}/{{ project_name }}"
state: directory
owner: "{{ backup_user }}"
group: "{{ backup_user }}"
mode: '0700'
- name: Deploy forced rsync command key for security
ansible.posix.authorized_key:
user: "{{ backup_user }}"
key: "{{ lookup('file', '{{ inventory_dir }}/ssh_keys/source_system.pub') }}"
key_options: 'command="rsync --server --sender -vlogDtprze.iLs .",no-port-forwarding,no-X11-forwarding'
# 5. Troubleshooting & “War Stories”
Der Großteil der Rsync-Fehler ist auf Pfadkonventionen, Berechtigungen oder SSH-Verbindungen zurückzuführen.
# Top 3 Fehlerbilder
# 1. Symptom A: Falsche Verzeichnisstruktur (The Trailing Slash Trap)
Die Zieldaten liegen in /mnt/backup/data/production_data/production_data.
- Fehlermeldung: Keine, aber falsches Ergebnis.
- Ursache: Fehlerhafter Umgang mit dem Trailing Slash (
/).rsync source_dir TARGET/(ohne Slash) => kopiertsource_dirinTARGET.rsync source_dir/ TARGET/(mit Slash) => kopiert den Inhalt vonsource_dirinTARGET.
- Lösung: Definieren Sie Ihre Pfade immer explizit und nutzen Sie
--dry-runvor der Ausführung.
# 2. Symptom B: Performance-Einbruch nach Update
Rsync-Läufe dauern plötzlich 10-mal länger als gewohnt, obwohl sich die Datenmenge nicht geändert hat.
- Analyse: Überprüfung der Logs. Vielleicht wurde die Option
-c(Checksummen-Vergleich) versehentlich aktiviert, oder das Zielsystem hat eine Platte mit starker Read-Latenz. - Lösung: Stellen Sie sicher, dass das
atime-Update auf dem Zieldateisystem deaktiviert ist (noatimein fstab), da Rsync die Lesezeitstempel unnötig aktualisieren kann, was unnötigen Schreib-Overhead erzeugt.
# 3. Symptom C: Permission Denied oder Inkonsistente Owner/Group
Rsync bricht mit Permission Denied ab, obwohl der ausführende Benutzer (rsync_user) Schreibrechte auf dem Ziel hat.
- Ursache: Rsync versucht, die Owner/Group der Quelle beizubehalten (wegen
-a). Wenn der Zielbenutzer kein Root ist, kann er diese Metadaten nicht setzen. - Lösung: Entweder Rsync als Root auf dem Ziel ausführen (wenn via SSH mit Schlüsselzugriff gesichert) oder die Optionen für Owner/Group weglassen:
rsync -rlptDanstelle von-a. Nutzen Siersync --chown=user:groupum die Berechtigungen explizit anzupassen.
# Recovery Szenarien
Verlorene Daten im Quellsystem: Wenn das Quellsystem ausfällt, ist der Restore trivial, da das Rsync-Ziel eine exakte Kopie der Quelldaten (inkl. Hardlink-Snapshots) enthält.
# Wiederherstellung vom Backup-Ziel auf den neuen Server
rsync -avz --progress \
${USER}@${DESTINATION_HOST}:${LAST_GOOD_SNAPSHOT_PATH}/ \
/mnt/restore_target/
War Story: Der --delete Schock
Wir hatten den Fall, dass ein Junior Admin einen Cronjob mit --delete und einem leeren Quellverzeichnis startete. Da Rsync die Quelle spiegeln soll, wurden die Daten im Ziel (das Haupt-Backup) sofort gelöscht.
- Lektion: Kritische Backup-Jobs mit
--deletemüssen unbedingt eine Vorprüfung des Quellverzeichnisses beinhalten (z.B. Zählen der Dateien), und die primäre Backup-Strategie sollte immer Hardlink-Snapshots nutzen, um eine sofortige Löschung zu verhindern.
flowchart TD
A[Rsync Fehlgeschlagen (Exit Code > 0)] --> B{SSH-Verbindung OK?};
B -- Nein --> C[Firewall/Key Check (Debug -v)];
B -- Ja --> D{Permission Denied?};
D -- Ja --> E{Läuft Rsync als Root?};
E -- Nein --> F[Nutze --no-o / --no-g oder Root-Zugriff];
E -- Ja --> G{SELinux/AppArmor Context?};
G -- Ja --> H[Check audit.log, set appropriate bools];
D -- Nein --> I{Falsche Datenmenge/Struktur?};
I -- Ja --> J[Check Trailing Slash Fehler];
J -- Ja --> K[Korrigiere Pfade, nutze -n];
I -- Nein --> L{Langsam oder Timeout?};
L -- Ja --> M[Check -z, --bwlimit, ionice];
# 6. Monitoring & Alerting
Der Schlüssel zum Monitoring von Rsync ist der Exit Code und die Log-Analyse.
# Metriken (Key Performance Indicators)
| Metrik | Beschreibung | Rsync Source |
|---|---|---|
| Exit Code | 0: Erfolg; 12: Protokollfehler; 23: Partielle Übertragung/I/O-Fehler; 24: Partielle Übertragung wegen Löschung (wichtig zu unterscheiden!) | $? |
| Transferiertes Datenvolumen | Wie viel MB/GB wurde tatsächlich übertragen (nicht gesamt). | --stats Output (Total bytes sent) |
| Durchsatz (Rate) | MB/s (Wichtig für Performance-Trend-Analyse). | --progress Output / --stats |
| Dateizähler | Anzahl der synchronisierten oder gelöschten Dateien. | --stats Output |
# Alerting-Regeln
- Exit Code Not Zero (Critical): Alert bei jedem Exit Code > 0.
- Exit Code 24 Management (Warning): Ein Exit Code 24 bedeutet, dass einige Dateien während der Übertragung verschwunden sind (oft temporäre oder rotierende Logdateien). Dies ist meist harmlos, sollte aber überwacht werden.
- Transferzeit-Abweichung (Warning): Wenn die Laufzeit eines inkrementellen Jobs die übliche Baseline um 50% überschreitet (Indiz für I/O-Stau oder Netzwerklatenz).
# Tools: Prometheus und Log-Analyse
Da Rsync keine eingebauten Prometheus-Exporter hat, muss das Monitoring über Wrapper-Skripte oder den Standard-Output erfolgen.
Wrapper-Skript-Beispiel:
#!/bin/bash
# rsync_wrapper.sh
# Führt Rsync aus und liefert Kennzahlen für den Prometheus Textfile Collector
/usr/bin/rsync -av --stats $SOURCE $DEST > /tmp/rsync_output.log 2>&1
EXIT_CODE=$?
# Parsing der relevanten Statistik (z.B. Total bytes sent)
BYTES_SENT=$(grep "Total bytes sent" /tmp/rsync_output.log | awk '{print $NF}' | tr -d ',')
cat << EOF > /var/lib/prometheus/node_exporter/rsync_backup_status.prom
# TYPE rsync_job_exit_code gauge
rsync_job_exit_code{job="production_data"} $EXIT_CODE
# TYPE rsync_bytes_transferred gauge
rsync_bytes_transferred{job="production_data"} $BYTES_SENT
EOF
exit $EXIT_CODE
# 7. Fazit & Empfehlung
Rsync ist die ultimative Waffe im Arsenal des Systemadministrators, wenn es um effiziente Dateisynchronisation geht. Seine Stärke liegt in der Delta-Kodierung und der Flexibilität, über nahezu jede Transportschicht (SSH, RSH, Dämon) arbeiten zu können.
Ich empfehle Rsync immer, wenn:
- Backups auf Dateiebene über begrenzte Bandbreiten laufen.
- Speichereffiziente Snapshots (via
--link-dest) benötigt werden. - Sie eine plattformunabhängige Synchronisationslösung benötigen.
Wann würde ich es nicht einsetzen?
- Transaktionale Integrität: Für Datenbanken oder VM-Images, die während des Kopiervorgangs kontinuierlich schreiben, ist Rsync ungeeignet, da es keine konsistenten Schnappschüsse (CoW) erstellen kann. Hier sind ZFS/Btrfs-Snapshots oder LVM-Snapshots vor dem Rsync-Lauf erforderlich.
- Massiv kleine Dateien: Der Overhead der Checksummen-Berechnung kann die Leistung beim Kopieren von Millionen winziger Dateien drosseln. Hier kann
tar | sshschneller sein.
Ausblick: Neuere Tools wie rsync-btrfs (für Btrfs) oder spezialisierte Cloud-Sync-Tools nutzen ähnliche Delta-Strategien, doch Rsync bleibt der performanteste und am besten verstandene Standard für file-level Replication.
# Anhang: Cheatsheet
| Befehl | Beschreibung | Anwendungsfall |
|---|---|---|
rsync -avz SOURCE/ USER@HOST:DEST/ |
Standard-Archivkopie, komprimiert, ohne Löschung. | Erster Sync-Lauf |
rsync -avn --delete SOURCE/ USER@HOST:DEST/ |
Testlauf (Dry Run) mit Löschung (sehr wichtig!) | Vor dem ersten Live-Lauf mit --delete |
rsync -a --link-dest=LAST/ SOURCE/ TODAY/ |
Erstellung eines Hardlink-Snapshots. | Rotierende inkrementelle Backups |
rsync --bwlimit=1000 ... |
Begrenzt die Bandbreite auf 1 MB/s. | Backup über begrenzte WAN-Leitung |
nice -n 10 ionice -c 3 rsync -a ... |
Führt Rsync mit niedrigster Systempriorität aus. | Sync auf produktiven Datenbank-Servern |
rsync -av --partial --progress ... |
Erlaubt Wiederaufnahme nach Verbindungsabbruch. | Instabile Netzwerkverbindungen |
rsync -c SOURCE DEST |
Erzwingt den Checksummen-Vergleich für jede Datei. | Integrity Check nach Datenrettung |
rsync -h |
Ausgabe in lesbaren (human) Formaten. | Analyse der --stats Ausgabe |