PSYNC, Backlog-Sizing und Resync-Mechanik verstehen
Redis-Replikation wirkt auf den ersten Blick simpel: ein Befehl, eine Verbindung, Daten fließen von Master zu Replica. Unter der Oberfläche entscheidet aber das PSYNC-Protokoll darüber, ob nach einer kurzen Netzwerkunterbrechung nur wenige Kilobyte oder der komplette Datensatz erneut übertragen werden, und eine falsch dimensionierte Backlog-Größe macht genau diesen Unterschied in der Praxis regelmäßig zunichte.
Inhaltsverzeichnis
- 1. Grundprinzip der Redis-Replikation
- 2. Das PSYNC-Protokoll im Detail
- 3. Partial Resync vs. Full Resync
- 4. Replication Backlog: Größe richtig dimensionieren
- 5. replica-read-only und Schreibschutz auf Replicas
- 6. Replikations-Lag erkennen und minimieren
- 7. Diskless Replication und RDB-Transfer
- 8. Verkettete Replikation: Sub-Replicas
- 9. Monitoring der Replikation mit INFO replication
- 10. Zusammenfassung
- 11. FAQ
1. Grundprinzip der Redis-Replikation
Die Redis-Replikation folgt einem asynchronen Master-Replica-Modell: Der Master verarbeitet Schreibbefehle, hängt sie an einen internen Replikations-Stream an und sendet diesen Stream kontinuierlich an alle verbundenen Replicas. Die Replicas wenden dieselben Befehle in derselben Reihenfolge auf ihre eigene Kopie der Daten an. Asynchron bedeutet dabei, dass der Master nicht auf die Bestätigung einer Replica wartet, bevor er dem Client die erfolgreiche Ausführung eines Schreibbefehls meldet, was Redis' geringe Latenz erhält, aber auch bedeutet, dass Replicas dem Master immer etwas hinterherhinken können.
Jede Replica verbindet sich zum Master über eine dedizierte TCP-Verbindung und identifiziert sich mit einer Replication ID und einem Offset, der angibt, bis zu welcher Position im Replikations-Stream sie bereits synchronisiert ist. Diese beiden Werte sind der Schlüssel zu allem, was in den folgenden Abschnitten beschrieben wird, denn sie entscheiden, ob eine Replica nach einer Unterbrechung nur die fehlenden Befehle nachholen kann oder komplett neu synchronisieren muss.
Wichtig für das Verständnis von Redis-Replikation ist, dass sie by design keine Konsistenzgarantie im Sinne von synchroner Replikation bietet. Redis kann über WAIT optional auf eine Mindestanzahl bestätigender Replicas warten, aber das ist eine explizite Anwendungsentscheidung, kein Standardverhalten. Wer diese Eigenschaft nicht kennt und sich blind auf sofortige Konsistenz zwischen Master und Replicas verlässt, baut Annahmen in seine Anwendung ein, die unter Last oder bei Netzwerkproblemen nicht mehr zutreffen.
2. Das PSYNC-Protokoll im Detail
Das PSYNC-Kommando, seit Redis 2.8 der Standardmechanismus für Replikation, ersetzte das ältere SYNC-Kommando, um intelligente Wiederaufnahme nach Verbindungsabbrüchen zu ermöglichen. Beim ersten Verbindungsaufbau sendet die Replica PSYNC ? -1, signalisiert damit, dass sie keine bekannte Replication ID und keinen Offset besitzt, und fordert eine vollständige Synchronisation an. Der Master antwortet mit +FULLRESYNC <replid> <offset> und beginnt die Übertragung eines RDB-Snapshots gefolgt vom laufenden Befehls-Stream.
Nach einer erfolgreichen initialen Synchronisation kennt die Replica sowohl die Replication ID des Masters als auch ihren aktuellen Offset. Bricht die Verbindung später ab, etwa durch ein kurzes Netzwerkproblem, sendet die Replica bei der Wiederverbindung PSYNC <replid> <offset> mit diesen gespeicherten Werten. Der Master prüft, ob er diese Replication ID kennt und ob der angeforderte Offset noch in seinem Replication Backlog vorhanden ist. Ist beides der Fall, antwortet er mit +CONTINUE und sendet nur die seit dem letzten bekannten Offset fehlenden Befehle, statt den kompletten Datensatz neu zu übertragen.
# Observe the PSYNC handshake at the protocol level (simplified)
# Initial sync from a brand-new replica:
# Replica -> Master: PSYNC ? -1
# Master -> Replica: +FULLRESYNC 8f3e9a2b1c4d5e6f 88213
# Master -> Replica: <RDB snapshot bytes>
# Master -> Replica: <live command stream from offset 88213>
# Reconnect after a brief network blip:
# Replica -> Master: PSYNC 8f3e9a2b1c4d5e6f 91045
# Master -> Replica: +CONTINUE 8f3e9a2b1c4d5e6f
# Master -> Replica: <only commands from offset 91045 onward>
# Inspect the replication ID and offset directly
redis-cli -p 6379 info replication | grep -E "master_replid|master_repl_offset"
Dieser Mechanismus ist der Grund, warum kurze Netzwerkunterbrechungen in gut konfigurierten Redis-Replikation-Setups praktisch unsichtbar bleiben: Statt Gigabyte an Daten erneut zu übertragen, tauschen Master und Replica nur die wenigen Befehle aus, die während der Unterbrechung angefallen sind. Wie groß dieses Zeitfenster für einen erfolgreichen Partial Resync tatsächlich ist, hängt direkt von der Größe des Replication Backlog ab, dem Thema des übernächsten Abschnitts.
3. Partial Resync vs. Full Resync
Der Unterschied zwischen Partial Resync und Full Resync hat massive Auswirkungen auf Netzwerklast, CPU-Last und die Zeit, bis eine Replica wieder vollständig synchron ist. Ein Full Resync erzwingt die komplette Neuerstellung eines RDB-Snapshots auf dem Master, dessen Übertragung über das Netzwerk und dessen Laden auf der Replica, was bei großen Datensätzen Minuten dauern und währenddessen signifikante CPU- und I/O-Last auf beiden Seiten erzeugen kann. Ein Partial Resync dagegen betrifft nur die Befehle, die tatsächlich seit der letzten bekannten Position fehlen, typischerweise wenige Kilobyte bis Megabyte.
Ein Full Resync wird immer dann erzwungen, wenn die Replica eine unbekannte Replication ID meldet, etwa nach einem Neustart des Masters mit geänderter ID, oder wenn der angeforderte Offset nicht mehr im Replication Backlog vorhanden ist, weil zu viel Zeit seit dem letzten Kontakt vergangen ist. Auch beim allerersten Verbindungsaufbau einer neuen Replica ist ein Full Resync unvermeidlich, da schlicht keine Basis für einen Partial Resync existiert.
# Count full vs. partial resyncs since the master started
redis-cli -p 6379 info stats | grep -E "sync_full|sync_partial_ok|sync_partial_err"
# sync_full:3 # forced complete resyncs (expensive)
# sync_partial_ok:47 # cheap partial resyncs (the goal)
# sync_partial_err:2 # partial attempted but failed, fell back to full
# A high sync_partial_err count relative to sync_partial_ok
# usually means the backlog is too small for typical outage windows
Ein hoher Anteil an sync_partial_err im Verhältnis zu sync_partial_ok ist ein zuverlässiges Warnsignal: Es zeigt, dass Replicas zwar versuchen, per Partial Resync wieder anzuknüpfen, aber regelmäßig scheitern, weil der Backlog nicht groß genug ist, um die typische Dauer von Netzwerkunterbrechungen abzudecken. Dieses Verhältnis sollte fester Bestandteil jedes Redis-Monitorings sein, denn es zeigt direkt, ob die aktuelle Backlog-Konfiguration zur tatsächlichen Netzwerkstabilität passt.
4. Replication Backlog: Größe richtig dimensionieren
Der Replication Backlog ist ein Ringpuffer im Arbeitsspeicher des Masters, der die zuletzt geschriebenen Befehle des Replikations-Streams für eine begrenzte Zeit vorhält. Seine Größe, konfiguriert über repl-backlog-size, bestimmt direkt, wie lange eine Replica offline sein kann, bevor ein Partial Resync nicht mehr möglich ist und stattdessen ein teurer Full Resync erzwungen wird. Der Standardwert von 1 MB ist für viele Produktionssetups deutlich zu klein.
Die korrekte Dimensionierung des Backlogs folgt einer einfachen Formel: Backlog-Größe = geschätzte maximale Ausfalldauer in Sekunden × Schreib-Durchsatz in Bytes pro Sekunde. Bei einem Schreib-Durchsatz von 2 MB pro Sekunde und einer angenommenen maximalen Netzwerkunterbrechung von 60 Sekunden ergibt das einen sinnvollen Backlog von mindestens 120 MB, mit Sicherheitsmarge eher 200 bis 256 MB. Diese Zahl sollte nicht geraten, sondern aus echten INFO-Statistiken über den tatsächlichen Schreib-Durchsatz und beobachteten Netzwerkunterbrechungsdauern abgeleitet werden.
# redis.conf: sizing the replication backlog
# Rule of thumb: expected_outage_seconds * write_bytes_per_second
repl-backlog-size 256mb
repl-backlog-ttl 3600
# Measure actual write throughput to size the backlog correctly
redis-cli -p 6379 info stats | grep instantaneous_input_kbps
# Check current backlog usage and how much headroom remains
redis-cli -p 6379 info replication | grep -E "repl_backlog_active|repl_backlog_size|repl_backlog_histlen"
Der Parameter repl-backlog-ttl bestimmt, wie lange der Backlog nach dem Trennen der letzten Replica im Speicher gehalten wird, bevor er verworfen wird. Ein zu niedriger Wert verschenkt die Partial-Resync-Fähigkeit bei kurzfristig getrennten und schnell wieder verbundenen Replicas unnötig. Wichtig ist außerdem, dass der Backlog erst angelegt wird, sobald mindestens eine Replica verbunden war, ein frisch gestarteter Master ohne jemals verbundene Replica hat noch keinen aktiven Backlog im Speicher.
5. replica-read-only und Schreibschutz auf Replicas
Standardmäßig ist der Parameter replica-read-only in Redis auf yes gesetzt, was bedeutet, dass Replicas Schreibbefehle direkter Clients ablehnen. Das ist eine bewusste Sicherheitsmaßnahme: Würden Clients versehentlich oder absichtlich Daten direkt auf eine Replica schreiben, würden diese Änderungen beim nächsten Replikations-Sync stillschweigend überschrieben, sobald der Master wieder Daten sendet, was zu verwirrenden, schwer nachvollziehbaren Datenverlusten führen kann.
Es gibt legitime Gründe, replica-read-only auf no zu setzen, etwa um auf einer Replica temporäre, nicht replizierte Daten zu speichern, die niemals zurück zum Master fließen sollen. Diese Praxis ist aber ein Antipattern in den allermeisten Fällen und sollte nur mit vollem Verständnis der Konsequenzen eingesetzt werden, da solche Schreibzugriffe beim nächsten Full Resync ersatzlos verloren gehen. In der überwiegenden Mehrheit der Setups sollte replica-read-only yes unverändert bleiben.
# redis.conf on every replica: enforce read-only by default
replica-read-only yes
# Attempting a write against a read-only replica fails clearly
redis-cli -p 6380 set foo bar
# (error) READONLY You can't write against a read only replica.
# Verify the setting live on a running replica
redis-cli -p 6380 config get replica-read-only
# 1) "replica-read-only"
# 2) "yes"
# Route write traffic exclusively to the master in application code
# Reads may be routed to replicas for load distribution
6. Replikations-Lag erkennen und minimieren
Replikations-Lag beschreibt die Verzögerung zwischen einem Schreibzugriff auf dem Master und dessen Sichtbarkeit auf einer Replica. Da Redis-Replikation asynchron arbeitet, existiert dieser Lag praktisch immer, in stabilen Netzwerken meist im Bereich weniger Millisekunden, kann aber bei Netzwerkproblemen, überlasteten Replicas oder sehr großen Einzelbefehlen auf Sekunden oder mehr anwachsen. Anwendungen, die unmittelbar nach einem Schreibzugriff von einer Replica lesen, etwa in einem Read-after-Write-Muster, können durch diesen Lag veraltete Daten erhalten.
Der zuverlässigste Weg, Lag zu messen, ist der Vergleich des master_repl_offset des Masters mit dem slave_repl_offset, den jede Replica über INFO replication auf dem Master meldet. Die Differenz dieser beiden Offsets, umgerechnet über den bekannten Schreib-Durchsatz, ergibt eine gute Schätzung der zeitlichen Verzögerung. Steigt diese Differenz kontinuierlich statt zu schwanken, deutet das darauf hin, dass die Replica mit der Verarbeitungsgeschwindigkeit des Masters nicht mehr mithalten kann, oft ein Zeichen für unzureichende Hardware-Ressourcen auf der Replica-Seite.
# On the master: see offset and lag reported for every replica
redis-cli -p 6379 info replication
# slave0:ip=10.0.1.12,port=6379,state=online,offset=884213,lag=0
# slave1:ip=10.0.1.13,port=6379,state=online,offset=884198,lag=1
# Compute lag manually from offsets if lag=0 looks suspicious
# lag_bytes = master_repl_offset - slave_repl_offset
redis-cli -p 6379 info replication | grep master_repl_offset
Für Anwendungen, die konsistente Reads unmittelbar nach einem Schreibzugriff benötigen, ist die pragmatischste Lösung, kritische Reads direkt gegen den Master zu richten statt gegen eine Replica, statt zu versuchen, Replikations-Lag vollständig zu eliminieren. Eine vollständige Elimination würde synchrone Replikation erfordern, die Redis standardmäßig nicht bietet und die bei Verwendung über WAIT spürbar Latenz und Durchsatz kostet.
7. Diskless Replication und RDB-Transfer
Bei einem klassischen Full Resync schreibt der Master zunächst einen RDB-Snapshot auf die lokale Festplatte und überträgt diese Datei anschließend an die Replica. Bei großen Datensätzen bedeutet das zusätzliche I/O-Last und Latenz durch den Umweg über die Festplatte. Diskless Replication, aktiviert über repl-diskless-sync yes, überspringt diesen Schritt: Der Master erstellt den RDB-Snapshot direkt im Arbeitsspeicher und streamt ihn ohne Zwischenspeicherung sofort an die Replica.
Der Parameter repl-diskless-sync-delay führt eine kurze, konfigurierbare Verzögerung ein, bevor der diskless Transfer beginnt, um mehreren neu verbundenen Replicas zu erlauben, sich denselben Snapshot-Stream zu teilen, statt für jede Replica einen eigenen Snapshot zu erzeugen. Das ist besonders relevant, wenn mehrere Replicas gleichzeitig neu aufgesetzt werden, etwa nach einem koordinierten Infrastruktur-Update, weil es die CPU-Last auf dem Master erheblich reduziert.
# redis.conf: diskless replication configuration
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-diskless-load disabled
# On the replica side, diskless loading avoids writing the
# incoming RDB to disk before applying it (Redis 6+)
# repl-diskless-load on-empty-db # safe default for most setups
Auf der Replica-Seite steuert repl-diskless-load, ob der eingehende RDB-Stream ebenfalls ohne Zwischenspeicherung auf Festplatte direkt geladen wird. Die Einstellung on-empty-db ist meist die sicherste Wahl, da sie diskless Loading nur erlaubt, wenn die Replica noch keine Daten hält, und damit verhindert, dass ein fehlgeschlagener Ladevorgang eine bereits funktionierende Replica in einen inkonsistenten Zustand versetzt.
8. Verkettete Replikation: Sub-Replicas
Redis erlaubt, dass eine Replica selbst wieder als Master für weitere Replicas fungiert, ein Muster, das als verkettete Replikation oder Sub-Replicas bezeichnet wird. Statt dass zehn Replicas direkt mit dem primären Master verbunden sind und dessen Netzwerkbandbreite und CPU für die Serialisierung des Replikations-Streams beanspruchen, verbinden sich beispielsweise nur zwei Replicas direkt mit dem Master, und jede dieser beiden bedient wiederum mehrere Sub-Replicas.
Dieses Muster reduziert die Last auf dem primären Master erheblich, besonders in Setups mit vielen geografisch verteilten Replicas, etwa wenn Replicas in mehreren Regionen benötigt werden und die Bandbreite zwischen den Regionen begrenzt ist. Der Kompromiss: Sub-Replicas erben den Replikations-Lag ihrer übergeordneten Replica zusätzlich zu deren eigenem Lag zum Master, wodurch sich die effektive Verzögerung über mehrere Ebenen hinweg akkumulieren kann. Für die meisten Setups mit einer überschaubaren Anzahl Replicas ist direkte Replikation vom primären Master weiterhin die einfachere und empfehlenswertere Wahl.
Mironsoft
Redis-Betrieb, Replikations-Tuning und Infrastruktur-Beratung
Häufige Full Resyncs statt schneller Partial Resyncs?
Wir analysieren euren Schreib-Durchsatz, dimensionieren den Replication Backlog korrekt und konfigurieren diskless Replication so, dass Replicas nach Netzwerkproblemen in Sekunden statt Minuten wieder synchron sind.
Backlog-Sizing
Backlog-Größe anhand echter Durchsatz- und Ausfalldaten korrekt berechnen
Lag-Monitoring
Replikations-Lag messbar machen und Alerting-Schwellen sinnvoll setzen
Topologie-Beratung
Verkettete Replikation und diskless Sync für eure Infrastruktur bewerten
9. Monitoring der Replikation mit INFO replication
Der Befehl INFO replication ist die zentrale Quelle für alle Kennzahlen rund um Redis-Replikation, sowohl auf dem Master als auch auf jeder Replica. Auf dem Master zeigt er für jede verbundene Replica deren IP, Port, Verbindungsstatus, aktuellen Offset und den gemeldeten Lag in Sekunden. Auf der Replica-Seite zeigt derselbe Befehl die Rolle, die Adresse des Masters, den Verbindungsstatus zum Master und den eigenen Replikations-Offset.
| Kennzahl | Wo sichtbar | Bedeutung |
|---|---|---|
| master_repl_offset | Master | Aktuelle Schreibposition im Replikations-Stream |
| slave_repl_offset | Replica | Zuletzt verarbeitete Position der Replica |
| sync_full | Master | Anzahl teurer kompletter Resyncs |
| sync_partial_ok | Master | Anzahl günstiger Partial Resyncs |
| repl_backlog_histlen | Master | Aktuell im Backlog vorgehaltene Datenmenge |
Ein produktionstaugliches Monitoring-Setup sollte mindestens vier Dinge kontinuierlich aus INFO replication und INFO stats ableiten: die Anzahl verbundener Replicas im Verhältnis zur erwarteten Anzahl, den gemeldeten Lag pro Replica, das Verhältnis von sync_full zu sync_partial_ok über die Zeit, und den Auslastungsgrad des Replication Backlog relativ zu dessen konfigurierter Größe. Alle vier Werte zusammen ergeben ein verlässliches Bild davon, ob die Replikation stabil läuft oder sich ein Problem anbahnt.
10. Zusammenfassung
Master-Replica-Replikation im Detail zu verstehen bedeutet vor allem, das PSYNC-Protokoll und seine Abhängigkeit vom Replication Backlog zu verinnerlichen. Ein korrekt dimensionierter Backlog macht den Unterschied zwischen einem unsichtbaren Partial Resync nach kurzen Netzwerkproblemen und einem teuren Full Resync, der Minuten dauert und die Produktionslast spürbar erhöht. Die Formel aus erwarteter Ausfalldauer mal Schreib-Durchsatz liefert eine solide Grundlage für diese Dimensionierung.
replica-read-only sollte in nahezu allen Setups aktiv bleiben, um versehentliche, beim nächsten Sync verlorene Schreibzugriffe zu verhindern. Diskless Replication reduziert I/O-Last bei großen Datensätzen, und regelmäßiges Monitoring von sync_full, sync_partial_ok und dem gemeldeten Lag pro Replica macht Probleme sichtbar, bevor sie zu echten Ausfällen oder veralteten Leseantworten in der Produktion führen.
Master-Replica-Replikation im Detail: Das Wichtigste auf einen Blick
PSYNC ermöglicht Partial Resync
Replication ID und Offset erlauben, nach Unterbrechungen nur fehlende Befehle nachzuholen.
Backlog korrekt dimensionieren
Ausfalldauer mal Schreib-Durchsatz als Formel, mit Sicherheitsmarge für Produktion.
replica-read-only aktiv lassen
Verhindert Schreibzugriffe, die beim nächsten Sync stillschweigend verloren gehen.
sync_full vs. sync_partial_ok überwachen
Zeigt direkt, ob die Backlog-Konfiguration zur echten Netzwerkstabilität passt.