Das Redis Slow Log zeigt mir exakt, welche Befehle den Server‑Thread blockieren und wie lange die Ausführung im Mikrosekundenbereich dauert, sodass ich gezielt Latenzquellen beseitige. Mit belastbaren Schwellenwerten, sauberem Export und korrelierenden Metriken optimiere ich die Performance nachhaltig.
Zentrale Punkte
Bevor ich tiefer einsteige, halte ich die wichtigsten Schwerpunkte fest, damit ich zielgerichtet vorgehe. Ich konzentriere mich auf klare Konfigurationen, wiederkehrende Muster und wirkungsvolle Gegenmaßnahmen. Zusätzlich achte ich auf den Bezug zum Client‑Kontext und zur Systemumgebung. So erreiche ich eine konsistente Analyse ohne Rauschen. Danach setze ich die Erkenntnisse direkt in Code‑, Datenmodell‑ und Monitoring‑Anpassungen um.
- Threshold und Log‑Länge sinnvoll wählen
- Muster über Zeit, Befehle und Clients erkennen
- Langsame Befehle durch Alternativen ersetzen
- Datenmodell und Caching straffen
- Slow Log ins Monitoring integrieren
Slow Log: Funktionsweise kurz erklärt
Ich verstehe das Slow Log als fokussierte Sicht auf die reine Ausführungszeit eines Kommandos im Single‑Thread von Redis. Der Server schreibt automatisch einen Eintrag, sobald die Dauer den über slowlog-log-slower-than gesetzten Schwellenwert in Mikrosekunden übersteigt. Jeder Datensatz liefert mir ID, Unix‑Timestamp, Ausführungszeit, Befehl mit Argumenten, Client‑IP/Port und optional einen Client‑Namen. Netzwerk‑I/O und Antwortübertragung blendet das Slow Log bewusst aus, wodurch ich die eigentliche Blockierzeit des Threads sehe. Genau diese Trennung hilft mir, logische Ursachen von Netzwerk‑ oder Client‑Latenz sauber zu unterscheiden und die Ursache besser einzugrenzen.
Konfiguration: Threshold und Log‑Länge
Für einen produktiven Start setze ich den Threshold oft auf 10.000 Mikrosekunden (ca. 10 ms), in Tests senke ich ihn temporär, um feinere Details zu erfassen. Die Anzahl gespeicherter Einträge steuere ich mit slowlog-max-len, typischerweise zwischen 128 und 4096, damit Lastspitzen gut sichtbar bleiben. Beide Werte ändere ich entweder in der redis.conf oder zur Laufzeit mit CONFIG SET, was mir flexible Diagnosefenster erlaubt. Vor größeren Lasttests senke ich den Schwellenwert, nach Abschluss hebe ich ihn wieder auf einen realistischen Produktionswert an. So halte ich das Log schlank, ohne wichtige Signale zu verlieren.
| Setting/Befehl | Bedeutung | Praxiswert |
|---|---|---|
| slowlog-log-slower-than | Schwellwert in Mikrosekunden für Einträge | Prod: 10.000 µs; Test: 1.000–5.000 µs |
| slowlog-max-len | Maximale Anzahl gespeicherter Einträge | 128–4096 Einträge je nach Volumen |
| SLOWLOG GET N | Zeigt die letzten N Datensätze | N = 10–100 für Ad‑hoc‑Checks |
| SLOWLOG LEN | Gibt die aktuelle Log‑Länge zurück | Regelmäßig prüfen |
| SLOWLOG RESET | Leert das Log | Vorher exportieren/sichern |
Slow Log im Alltag auslesen
Im täglichen Betrieb rufe ich die jüngsten Einträge mit SLOWLOG GET ab und prüfe mit SLOWLOG LEN, wie stark sich langsame Befehle häufen, bevor ich bei Bedarf mit SLOWLOG RESET das Log leere. Ein Export vor dem Reset verhindert, dass ich wertvolle Historie verliere, besonders wenn ich Trends über mehrere Tage vergleichen will. In Cluster‑Setups beziehe ich jede Instanz und jedes Replica ein, da das Slow Log instanzspezifisch ist und sonst blinde Flecken bleiben. Für strukturierte Analysen verknüpfe ich die Einträge mit Client‑Informationen wie IP, Port und gesetztem Namen, damit ich die Quelle im Anwendungscode eindeutig identifiziere. Zusätzlich schaue ich in INFO‑Statistiken, um Frequenzen und Latenzen im Kontext der Gesamtnutzung zu bewerten.
Von Ereignissen zu Mustern: Systematische Analyse
Ich betrachte zuerst die am häufigsten auffälligen Befehle mit hoher Laufzeit und prüfe danach, wie oft sie insgesamt auf der Instanz auftreten. Ein Befehl, der selten überschreitet, stört weniger als einer, der minimal über dem Threshold liegt, jedoch tausendfach pro Minute. Zeitliche Cluster während Cron‑Jobs, Backups oder Traffic‑Spitzen verraten mir, ob Arbeitsspitzen oder Applikationsroutinen Ursache sind. Über INFO commandstats erhalte ich Kontext zu Aufrufzahlen und durchschnittlichen Dauern, was ich bequem über den Beitrag INFO commandstats vertiefe. Identifizierte Client‑Namen aus CLIENT LIST verbinde ich mit Services oder Microservices, wodurch ich die Verantwortung zuordne und die Optimierung gezielt plane.
Optimierungsstrategien: Befehle und Datenmodell
Ich ersetze teure Befehle wie KEYS auf großen Datenmengen durch SCAN mit angepassten Cursors, um Blockierungen zu vermeiden und die Latenz zu senken. Wo Lua‑Skripte zu lang laufen, spalte ich Logik in mehrere kleinere Schritte oder greife auf voraggregierte Daten zurück. Häufig sind lange Laufzeiten ein Symptom des Datenmodells: Ich teile sehr große Listen, Sets oder Hashes, nutze zusätzliche Indizes oder passendere Datentypen. Bei wiederkehrenden teuren Berechnungen cache ich Ergebnisse näher an der Anwendung und invaliere kontrolliert, statt immer wieder Neuaufbau zu erzwingen. Typische Fehlkonfigurationen und Anti‑Patterns fasse ich praxisnah über typische Fehlkonfigurationen zusammen, damit ich vermeidbare Fehler schneller ausräume und die Effizienz steigere.
Client‑Kontext und Anwendungscode
Im Code reduziere ich Roundtrips durch Pipelining und Bündelung, wodurch ich die reine Serverzeit zwar nicht ändere, aber die erlebte Latenz pro Aufruf stark senke. Parameter aus Slow‑Log‑Einträgen zeigen mir, wo unnötige Schleifen oder wiederholte Zugriffe entstehen. Ich sorge dafür, dass Clients sinnhafte Namen via CLIENT SETNAME vergeben, damit die Zuordnung im Team sofort klar ist. Schreiblasten verteile ich, indem ich Hot‑Keys identifiziere, Zugriffsmuster streue und TTL‑Strategien überprüfe. Bei Migrationsphasen oder Funktionsflags beobachte ich gezielt die Einträge betroffener Pfade, um Auswirkungen zeitnah zu erkennen und die Qualität zu sichern.
Ressourcen, Topologie und Latenzquellen
Nicht jede Langsamkeit stammt aus ineffizienten Befehlen, deshalb prüfe ich CPU‑Spitzen, Speicherengpässe und Netzwerklatenz parallel zu den Einträgen im Slow Log. Eine ungünstige Shard‑Verteilung, zu wenige Replikate oder lange Cross‑Zone‑Wege erhöhen die wahrgenommene Dauer. Ich prüfe ferner RDB/AOF‑Einstellungen und Hintergrundjobs, die den Serverprozess kurzzeitig unter Druck setzen. Unter hoher Last ziehe ich Skalenoptionen in Betracht, wenn das Datenmodell bereits optimiert ist und die Befehlswahl stimmt. Erst die Korrelation mit Systemmetriken macht für mich klare Ursache‑Wirkungs‑Ketten sichtbar.
Slow Log in Monitoring integrieren
Ein dediziertes Dashboard zeigt mir die Entwicklung der Log‑Länge, die Anzahl langsamer Befehle pro Service und Korrelate wie CPU‑ und Speicherauslastung. Ich binde die Slow‑Log‑Daten in bestehende Observability‑Pipelines ein und schaffe so eine fortlaufende Überwachung. In grafischen Oberflächen filtere ich nach Befehlen, Zeiten und Clients, um Auffälligkeiten schneller zu isolieren. Für praktische Workflows setze ich auf Werkzeuge mit Slow‑Log‑Ansichten, Workbench und Exportfunktionen, wie ich sie im RedisInsight Guide beschreibe. Dadurch verkürze ich den Diagnoseweg deutlich und erhöhe die Aussagekraft der Metriken.
Praxisleitfaden: Schritt‑für‑Schritt
Zuerst stelle ich sicher, dass slowlog-log-slower-than und slowlog-max-len sinnvoll gesetzt sind, damit ich weder Rauschen erzeuge noch relevante Signale verliere. Danach lese ich die jüngsten Datensätze aus, sichere diese und identifiziere auffällige Befehle mit Blick auf Häufigkeit und Dauer. Im nächsten Schritt untersuche ich Zeitfenster, verknüpfe CLIENT‑Namen und suche Muster in wiederkehrenden Parametern. Daraus leite ich konkrete Maßnahmen im Code, im Datenmodell sowie in Caching‑Konzepten ab. Zum Schluss überführe ich die Auswertung in mein permanentes Monitoring, damit ich Trends früh erkenne und Regressionen verhindere.
Erfahrungswerte und Tuning‑Kriterien
Ein Startwert von 10 ms als Schwelle funktioniert für viele Produktionsumgebungen gut, während niedrigere Werte in Tests hilfreiche Details liefern. Die Log‑Länge passe ich so an, dass sie typische Tages‑ oder Wochenmuster abbildet, ohne Speicher zu vergeuden. Ich setze eine Baseline auf, dokumentiere typische Befehlsverteilungen und achte auf schleichende Veränderungen. Nach Deployments werfe ich bewusst einen Blick ins Slow Log, um früh zu erkennen, ob neue Features ungewollte Latenzpfade erzeugen. Diese Disziplin erzeugt verlässliche Aussagen darüber, wann ich nachjustieren sollte und wie ich die Leistung langfristig hochhalte.
Grenzen und Interpretationshinweise des Slow Logs
Ich berücksichtige, dass das Slow Log nur die reine Ausführungszeit im Server‑Thread misst. Wartezeiten in der Command‑Queue, TLS‑Handshake‑Kosten oder der Transport großer Antworten über das Netzwerk tauchen dort nicht auf. Ebenso werden Befehlsargumente im Slow Log aus Speichergründen begrenzt und eventuell gekürzt, weshalb ich Parameter nur als Hinweis und nicht als vollständige Wahrheit betrachte. Weil das Log schwellenwertbasiert arbeitet, erhalte ich eine Stichprobe der langsamsten Fälle und keine vollständige Verteilung. Deshalb ergänze ich Auswertungen mit Latenz‑Percentiles aus dem Monitoring und nutze bei Bedarf den integrierten LATENCY‑Monitor (Schwelle via latency-monitor-threshold), um sporadische Spikes zu erkennen.
Cluster‑ und Replikationsbesonderheiten
In Cluster‑Setups prüfe ich, ob langsame Kommandos auf einzelne Slots oder Shards konzentriert sind. Cross‑Slot‑Operationen (z. B. MGET auf Keys ohne Hash‑Tag) führen zu Fehlern oder Umwegen und erzeugen unnötige Roundtrips, die im Slow Log nicht sichtbar sind, jedoch die wahrgenommene Latenz erhöhen. Rebalancings, Failover und Replikationsnachläufe beeinflussen die Systemlast: Kommandos wie WAIT können absichtlich länger dauern, bis Acknowledgements eingetroffen sind. Auf Standby‑Replikas gelten andere Zugriffsprofile; dort prüfe ich slowlog‑Einträge getrennt, weil Leselasten, Sync‑Aufwände und Hintergrundprozesse voneinander abweichen. Für eine saubere Diagnose exportiere ich das Slow Log von jeder Instanz und korreliere die Zeitstempel über alle Knoten.
Persistenz, Forks und Speicherverhalten
Ich behalte RDB‑Snapshots und AOF‑Rewrites im Blick: Beim Forken des Redis‑Prozesses kann Copy‑on‑Write zu temporär hohem Speicherbedarf und CPU‑Peaks führen, die wiederum Kommandolaufzeiten verlängern. AOF‑Einstellungen (z. B. appendfsync) beeinflussen Schreiblatenzen; „everysec“ ist meist ein guter Kompromiss, während „always“ die Haltbarkeit erhöht, aber Spitzen begünstigen kann. Zusätzlich beachte ich aktive Speicherdefragmentierung, Evictions und das Abarbeiten abgelaufener Keys. Große Einzelkeys (z. B. Hashes mit zehntausenden Feldern) verursachen in Expire‑Zyklen oder bei Löschungen spürbare Pausen. Mit lazyfree‑Optionen (z. B. lazyfree‑lazy‑eviction) entlaste ich den Hauptthread, indem ich das Freigeben großer Strukturen asynchron durchführen lasse, sofern das Workload‑Profil dazu passt.
Blocking‑, Multi‑Key‑ und Skript‑Befehle
Ich differenziere zwischen Kommandos mit linearem Aufwand (O(N)) und logarithmischen oder konstanten Varianten. SORT, SUNIONSTORE, ZUNIONSTORE oder HGETALL über große Strukturen schlagen häufig im Slow Log auf. EVAL/EVALSHA sind zwar atomar und praktisch, können aber durch interne Schleifen den Server‑Thread lange binden; kleinere, gut abgestimmte Teilschritte sind hier besser. Blocking‑Befehle wie BLPOP oder XREAD BLOCK blockieren primär den Client, nicht den Server‑Thread – werden aber dann kritisch, wenn sie mit sehr großen Datenstrukturen kombiniert sind. Beim Scannen meide ich breite MATCH‑Pattern ohne Indexlogik und kalibriere COUNT so, dass ich die Last steuerbar halte; SCAN schützt vor Vollblockaden, ist aber kein Freifahrtschein für ungerichtete Suchläufe.
Export, Automatisierung und Datenaufbereitung
Für reproduzierbare Analysen exportiere ich das Slow Log regelmäßig und vereinheitliche das Format. Ich reiche die Einträge mit Client‑Namen, Usern (ACL) und Service‑Tags an, damit Ownership eindeutig ist. Ein einfacher Workflow per Shell hilft mir für Ad‑hoc‑Exporte:
# JSON-ähnlicher Export der letzten 500 Einträge
redis-cli SLOWLOG GET 500 > slowlog.raw
# CSV-Beispiel (ID;Timestamp;Dauerµs;Befehl;Client)
# Hinweis: Argumente können im Slow Log gekürzt sein
redis-cli --raw SLOWLOG GET 200 | awk '
BEGIN{FS="\n"; OFS=";"}
/1\)/{id=$2} /2\)/{ts=$2} /3\)/{dur=$2} /4\)/{cmd=$0; gsub(/^[^"]*"/,"",cmd); gsub(/"[^$]*/,"",cmd)} /5\)/{client=$0}
/5\)/{print id,ts,dur,cmd,client}
' > slowlog.csv
In Automationspipelines rufe ich die Daten auf allen Knoten ab, normalisiere Zeitstempel (UTC) und bilde Metriken pro Befehl, pro Client und pro Zeitfenster. Ich achte darauf, vor jedem SLOWLOG RESET zu exportieren und die Rotationsfrequenz an die Log‑Länge anzupassen, damit keine Peaks verloren gehen.
Vorgehensmuster für Incident‑Response
In akuten Fällen sichere ich zuerst den Status quo: Ich prüfe SLOWLOG LEN, exportiere die letzten Einträge großzügig und erhöhe slowlog-max-len temporär, damit keine Daten wegrotieren. Dann senke ich den Threshold moderat, um auch knapp unter der bisherigen Schwelle liegende Muster zu sehen. Parallel kontrolliere ich CPU, RSS‑Speicher, Page‑Faults, Netzwerk‑RTT sowie Persistenzereignisse (RDB/AOF). Treten einzelne Kommandos massenhaft auf, reduziere ich sie kurzfristig durch Feature‑Flags oder engere Ratenlimits. Bei Hot‑Keys streue ich Zugriffe (Key‑Hashing/Shard‑Spread) und erhöhe bei Bedarf Replikationskapazität. Sobald die Spitze gebrochen ist, führe ich eine tiefergehende Ursachenanalyse durch und setze dauerhafte Fixes im Code und Datenmodell um.
Qualitätssicherung vor und nach Deployments
Vor Releases senke ich in Staging die Slow‑Log‑Schwelle deutlich, um mikro‑ineffiziente Stellen früh zu entdecken. Ich definiere akzeptierte Latenzbudgets (z. B. p95/p99 je Befehl) und vergleiche sie mit einer dokumentierten Baseline. Nach dem Rollout beobachte ich Slow‑Log‑Einträge für die betroffenen Services engmaschig; Abweichungen führen zu einem schnellen Rollback oder zu gezielten Optimierungen. Ein Canary‑Rollout pro Shard/Zone hilft mir, Effekte isoliert zu beobachten. Wichtig ist die Kommunikation: Jeder Client setzt einen sprechenden Namen, damit ich Slow‑Log‑Einträge sofort einem Owner zuordnen kann – das beschleunigt die Problemlösung enorm.
Entscheidungslogik für Threshold und Log‑Länge
Ich wähle den Threshold nicht nur absolut, sondern kontextsensitiv: Auf sehr schnellen Knoten mit NVMe und reichlich CPU senke ich ihn in Produktionszeiten eher auf 5–8 ms, um feine Hotspots zu erkennen; bei kostengünstiger Hardware oder starkem Burst‑Traffic bleibe ich konservativer, damit das Log signalstark bleibt. Die Log‑Länge skaliere ich mit der Befehlsrate und dem Exportintervall: Je höher die Befehlsfrequenz, desto größer das Fenster (z. B. 2048–4096), damit ich ganze Traffic‑Zyklen erfasse. In Lasttests setze ich die Länge bewusst hoch und plane Exporte zeitnah ein, um keine Spitzen zu verlieren. In Ruhephasen fahre ich die Werte zurück, um Speicher zu schonen und die Analyse fokussiert zu halten.
Häufige Muster in der Praxis
Typisch sehe ich drei Klassen von Ursachen: Erstens teure O(N)‑Operationen auf großen Strukturen (SORT, große Set/Hash‑Unionen, volle Iterationen), zweitens Nebenwirkungen des Systems (Forks, Defrag, Evictions) und drittens Anwendungsmuster (N+1‑Zugriffe, doppelte Berechnungen, fehlendes Caching). Gegenmaßnahmen leiten sich direkt ab: Befehlsersatz und Eingrenzung der Datenmenge, Entkopplung schwerer Operationen in Jobs/Queues, asynchrone Freigaben großer Objekte, saubere TTL‑ und Invalidierungsstrategien sowie mehr Aggregation nahe am Verbraucher. Ich verbinde diese Maßnahmen stets mit Metriken, damit Erfolge messbar und Regressionen schnell sichtbar sind.
Kompakte Zusammenfassung
Ich nutze das Slow Log, um die reine Serverzeit teurer Befehle sichtbar zu machen, setze passende Schwellen und sichere die Datensätze vor Resets. Mit Konfigurationen über redis.conf oder CONFIG SET halte ich den Diagnosezeitraum flexibel, ohne unnötigen Speicher zu verbrauchen. Aus den Einträgen leite ich Muster über Befehle, Zeiten und Clients ab und optimiere anschließend Kommandowahl, Datenmodell, Caching und Anwendungscode. Parallel korreliere ich Slow‑Log‑Statistiken mit Systemmetriken sowie APM‑Signalen, damit ich Ursachen klar zuordne. So bleibt die Performance planbar und Latenzprobleme verlieren ihren Überraschungseffekt.


