...

Linux PSI für präzise Performanceanalyse und Monitoring

Linux PSI liefert mir Kennzahlen, die zeigen, wie lange Tasks auf CPU, Speicher oder I/O warten und damit echte Engpässe sichtbar machen. So erkenne ich zielgenau, wann Systeme blockieren, statt nur Auslastung zu messen, und leite aus den Pressure-Werten direkte Maßnahmen für Performanceanalyse und Monitoring ab.

Zentrale Punkte

  • some/full: Frühwarnsignal vs. kritische Blockade
  • cpu/memory/io: Druck je Ressource klar getrennt
  • avg10/60/300: Zeitfenster für Trendbewertung
  • Cgroups: Verursacher und Betroffene identifizieren
  • Trigger: Automatisch reagieren bei Schwellenüberschreitung

Was Linux PSI misst und warum es zählt

Ich lese aus Pressure-Metriken ab, wie viel echte Arbeitszeit Prozesse verlieren, weil CPU-Zeit, RAM oder I/O fehlen. Klassische Auslastungswerte zeigen lediglich, wie stark Ressourcen benutzt werden, während PSI offenlegt, wie oft das System faktisch stillsteht. Genau das macht die Unterscheidung zwischen kurzer Warteschlange und harter Blockade sichtbar. In dynamischen Setups mit Containern und dichten Deployments erkenne ich dadurch Engpässe früher und ordne sie eindeutig einer Ressource zu. So priorisiere ich Tuning-Maßnahmen gezielt und spare mir Ratespiele über die eigentliche Ursache.

Linux PSI aktivieren und prüfen

Ich prüfe zuerst, ob PSI aktiv ist, indem ich die Dateien unter /proc/pressure lese; liefern cpu, memory und io dort Werte, ist alles bereit. Fehlen Daten, aktiviere ich PSI mit dem Kernel-Bootparameter psi=1 oder stelle sicher, dass CONFIG_PSI=y im Kernel gesetzt ist. Das Feature steht ab Kernel 4.20 bereit und ist in aktuellen Distributionen häufig schon eingeschaltet. Für schnelle Checks genügen einfache Aufrufe wie cat /proc/pressure/cpu, die mir avg10, avg60, avg300 und total liefern. So weiß ich binnen Sekunden, ob mein System aussagefähige Metriken bereitstellt.

Die Dateien unter /proc/pressure verstehen

In /proc/pressure liegen drei Dateien für cpu, memory und io, die je zwei Druckarten ausgeben: some und full. some signalisiert, dass mindestens ein Task warten musste, während full anzeigt, dass alle nicht-idlen Tasks gleichzeitig festhängen. Dazu erhalte ich gleitende Durchschnitte über 10, 60 und 300 Sekunden sowie einen kumulativen total-Wert. Anhand dieser Zeitfenster unterscheide ich kurze Peaks von dauerhaften Problemen. So bewerte ich nüchtern, ob nur vereinzelte Spitzen auftreten oder ob anhaltender Druck vorliegt.

some vs. full in der Praxis

Ich werte some als Frühindikator und full als harten Alarm, denn full beschreibt Phasen, in denen produktive Arbeit faktisch steht. Steigt some bei CPU, prüfe ich Scheduling, Locks und Lastverteilung; helfen kann dann das Optimieren von Threads oder das Messen der Scheduler-Latenz messen. Hohe memory-some-Werte deuten oft auf Page-Reclaims, Swapping oder aufwändige Allokationen hin. Wächst io-some, schaue ich auf Warteschlangen, Prioritäten und konkurrierende Zugriffe. Ich treffe Entscheidungen nicht nach Bauchgefühl, sondern nach klaren Signalen.

Systemweite vs. Cgroup-basierte Auswertung

Ich betrachte zuerst systemweite Werte, um ein Gesamtbild zu erhalten, und wechsle danach in Cgroups, um Verursacher zu identifizieren. Mit cgroup v2 finde ich pro Service oder Container eigene pressure-Dateien, was mir die Zuordnung zu Pods, Slices oder Units erlaubt. Dieses Vorgehen trennt Symptome von Quellen, statt alle Lasten pauschal dem Host anzulasten. Danach passe ich Quotas, CPU-Shares oder Memory-Limits gezielt an. So erhöhe ich Fairness und reduziere gegenseitige Beeinflussung.

PSI in Monitoring, Dashboards und Kubernetes

Ich sammle PSI selten manuell, sondern lasse Exporter die Daten als Zeitreihen erfassen, damit Dashboards Trends und Korrelationen zeigen. In Kubernetes lese ich PSI auf Node-, Pod- und Container-Ebene, was eine saubere Trennung von Verbrauch und Engpass je Workload bringt. So erkenne ich, ob ein einzelner Pod Wartezeiten für andere erhöht oder ob das Problem knotenweit auftritt. Alerts setze ich auf full-Entwicklungen und auf anhaltend hohe some-Werte. Dadurch reagiere ich proaktiv, bevor Nutzer Wartezeiten spüren.

Typische Einsatzszenarien und sinnvolle Schwellen

Ich setze PSI bei Lasttests ein, um zu prüfen, ob Antwortzeiten durch CPU-, Speicher- oder I/O-Druck steigen und ob dies nur kurz oder dauerhaft geschieht. In der Kapazitätsplanung beobachte ich avg300, um wiederkehrende Muster zu erkennen und rechtzeitig Ressourcen zu erweitern oder Workloads zu verschieben. Für Autoscaling nutze ich Trigger nahe an der Schwelle, an der full auftritt, damit ich rechtzeitig reagiere. Bei schleichender Performanceverschlechterung vergleiche ich Baselines vor und nach Releases, um Effekte transparent zu machen. So entscheide ich faktenbasiert und investiere dort, wo die meiste Wirkung entsteht.

Tabellarischer Schnellcheck der PSI-Metriken

Ich halte mir beim Blick auf PSI eine einfache Zuordnung bereit, damit ich schneller zur richtigen Hypothese komme. Die folgende Tabelle verdichtet die Deutung von some und full je Ressource und gibt erste Handlungsoptionen. Sie ersetzt keine tiefere Analyse, spart mir jedoch wertvolle Zeit im Betrieb. Entscheidend bleibt, kurzzeitige Peaks anders zu bewerten als längere Phasen. Genau dafür nutze ich die Gleitmittelwerte avg10, avg60 und avg300 als Kontext.

Ressource some-Signal full-Signal Häufige Ursachen Mögliche Maßnahmen
CPU Gelegentliche Wartephasen Alle Tasks blockiert Scheduler-Konflikte, Locks, zu viele Threads Thread-Pools justieren, Locks entschärfen, CPU-Shares/Quotas anpassen
Memory Reclaims, Page-Faults, Allokationsstau Starker Druck, Swap dominiert Übercommit, große Heaps, Cache-Druck Limits prüfen, Allokationen optimieren, Swapping reduzieren
I/O Wachsende Warteschlangen I/O steht übergreifend Überbuchte Disks/Netz, konkurrierende Zugriffe Prioritäten, Batching, Queue-Tuning, getrennte Volumes

Speicherdruck richtig deuten

Ich werte memory.pressure im Zusammenspiel mit RSS, Cache-Anteilen und Swap-Nutzung aus, weil erst diese Kombination tragfähige Aussagen liefert. Häufig steckt hinter hohem some eine Phase intensiver Freigaben oder ein Anstieg an Page-Faults, der sich mit besseren Allokationsmustern glätten lässt. Wird full sichtbar, stoppe ich Experimente und reduziere zuerst den Druck durch Limits oder weniger aggressive Caches. Einen vertiefenden Einstieg in das Thema gibt mir Memory-Pressure mit praktischen Hinweisen zu RAM-Tuning. So verhindere ich, dass unkontrolliertes Swapping Antwortzeiten dominiert.

I/O-Engpässe erkennen und adressieren

Ich prüfe io.pressure zusammen mit Latenzen, Re-Queue-Raten und Queue-Tiefen, weil reine Durchsatzwerte Engpässe verschleiern. Hoher some bei moderater Auslastung weist mich oft auf ungleichmäßige Zugriffsprofile hin, die sich mit Batching oder Priorisierung glätten lassen. Bei first-byte-Lags und wachsendem full setze ich auf Entkopplung per asynchronem I/O und getrennte Volumes für Hotpaths. Für detaillierte Diagnosen nutze ich Messreihen und die im Alltag bewährte Anleitung zu I/O-Wait analysieren. Damit treffe ich zielgenaue Entscheidungen statt Vermutungen.

PSI vs. Load Average und klassische Metriken

Ich stelle PSI bewusst neben Load Average, CPU-Auslastung, iowait und Speicherauslastung, um die Lücken zwischen diesen Sichtweisen zu schließen. Hoher Load bei niedriger cpu.pressure zeigt mir oft nur, dass viele Tasks aktiv rechnen können – ohne systemweite Staus. Umgekehrt ist steigende cpu.pressure bei moderater Auslastung ein Hinweis auf Scheduler-Konflikte oder Lock-Contention. Bei I/O gilt: iowait alleine sagt mir nicht, wie stark das Gesamtsystem darunter leidet; io.pressure quantifiziert, wie viel Arbeitszeit dabei verloren geht. Genau diese Übersetzung von “Auslastung” in “verlorene Zeit” macht meine Entscheidungen deutlich zuverlässiger.

avg-Fenster und total präzise lesen

Ich sehe die Werte avg10/60/300 als Prozentanteile der Zeit, in der Tasks blockiert waren. Ein avg10 von 2.50 bedeutet, dass in den letzten 10 Sekunden 2,5% der potenziellen Arbeitszeit verloren gingen. Der total-Wert akkumuliert Stall-Zeit seit Boot (in fein aufgelösten Zeiteinheiten) und zeigt mir damit die Fläche unter der Kurve. Für Kapazitätsplanung schaue ich auf die Steigung von total über Tagesprofile: Wird die Linie in Peak-Phasen deutlich steiler, plane ich Entlastung. Für Betriebssignale bewerte ich Muster: ein kurzes Aufflackern in avg10 beunruhigt mich weniger als eine parallele Erhöhung von avg60 und avg300, die auf strukturellen Druck hindeutet.

Cgroups praktisch: Struktur, Pfade und Berechtigungen

Ich arbeite in cgroup v2 mit den pressure-Dateien direkt in den jeweiligen Service-, Slice- oder Pod-Verzeichnissen. So erkenne ich pro Unit, Pod oder Container, ob Druck lokal entsteht oder nur weitergereicht wird. Systemd-Units, Kubernetes-Pods und benutzerdefinierte Gruppen lassen sich auf diese Weise klar voneinander trennen. Gelingt die Zuordnung, drossele ich gezielt: CPU-Quotas enger, CPU-Shares gerechter, Memory-Limits realistisch. Praktisch achte ich darauf, die Messung dort zu machen, wo sie wirkt – in genau der Cgroup, die auch die Limits setzt. Das verhindert, dass ich Symptome an einer Stelle bekämpfe, während die eigentliche Quelle unberührt bleibt.

Alerting-Strategien ohne Alarmflut

Ich definiere Alarme so, dass sie Trends und Persistenz berücksichtigen. Für Früherkennung setze ich Schwellwerte auf some, kombiniere sie mit Beobachtungsfenstern und Hysterese, und prüfe, ob avg10 und avg60 erhöht bleiben. Für akute Eingriffe verknüpfe ich full mit kurzen Fenstern und automatischen Reaktionen (Skalierung, Priorisierung, Drosselung). Um Flattern zu vermeiden, lasse ich erst auslösen, wenn ein Zustand mehrfach bestätigt ist, und schalte erst wieder zurück, wenn die Werte signifikant unter die Rückkehrschwelle fallen. Alerts binde ich an Service-SLOs: Wenn p95-Latenzen steigen und gleichzeitig Druck zunimmt, ist der Befund belastbar – reine Auslastung alleine genügt mir dafür nicht.

Praxisbeispiele: Muster, die ich sofort erkenne

Ich sammle gerne wiederkehrende Muster, weil sie Entscheidungen beschleunigen:

  • CPU: Lock-Contention statt “zu wenig Cores” – cpu.some steigt, obwohl die CPU-Auslastung nicht am Limit ist. Ich untersuche Hotlocks, reduziere Thread-Fächerung und glätte Spitzen mit Backpressure. Das bringt oft mehr als zusätzliche Cores.
  • Memory: Reclaim-Spirale – memory.some klettert und schwankt mit Page-Faults, während Swap aktiv wird. Ich senke Cache-Aggressivität, reduziere Heap-Spitzen (z. B. Batchgrößen), passe Limits an und verhindere so, dass memory.full überhaupt sichtbar wird.
  • I/O: Unausgeglichene Zugriffe – io.some steigt bei gleichzeitig normalem Durchsatz. Ich entkopple Lese-/Schreibpfade, bündele kleine I/Os zu Batches und verteile Hotpaths auf eigene Volumes. So reduziere ich Wartezeiten, ohne zwangsläufig den reinen Durchsatz zu erhöhen.

Grenzen und Stolpersteine bei der Interpretation

Ich behalte im Hinterkopf, dass PSI Wartezeit misst – nicht die absolute Auslastung. Ein CPU-bound Batchjob kann hohe Auslastung zeigen, ohne cpu.pressure zu erhöhen, solange genug Kerne verfügbar sind. Umgekehrt kann geringer Durchsatz mit hoher io.pressure ein klarer Stau sein. In virtualisierten Umgebungen prüfe ich außerdem, ob Limits oder Affinitäten lokale Engpässe erzeugen: Ein Container, der nur auf wenige Cores gepinnt ist, kann starken cpu.pressure zeigen, obwohl der Host freie Ressourcen hat. Wichtig ist auch, systemweite und cgroup-lokale Sicht zu vergleichen – nur so erkenne ich, ob ich das Problem am richtigen Ort löse.

Operative Leitplanken: Sampling, Overhead und Visualisierung

Ich halte das Sampling einfach: ein Intervall von 1–5 Sekunden reicht mir für operative Entscheidungen, weil die avg-Fenster bereits glätten. Den Overhead von PSI bewerte ich als vernachlässigbar, zumal ich die Messung systemnah halte und nur wenige, gut platzierte Zeitreihen erfasse. Für Visualisierung stelle ich pro Ressource Panels nebeneinander (some/full, avg10/60/300, total) und korreliere sie mit Latenz- und Fehlerraten. In Post-Mortems zeichne ich die Steigung von total gegen Deployments, Releases oder Konfigurationswechsel – so wird transparent, welche Maßnahmen Druck tatsächlich senken.

Gezielte Gegenmaßnahmen pro Ressource

Ich leite aus den Mustern konkrete Schritte ab, ohne reflexartig Hardware nachzulegen:

  • CPU: Thread-Pools und Concurrency-Guards begrenzen, Hotlocks entschärfen (Granularität/Locking-Strategie), Last fair verteilen (Shares/Quotas), Topology berücksichtigen (NUMA, Affinität). Erst wenn lokale Entlastung nicht greift, skaliere ich horizontal oder vertikal.
  • Memory: Allokationen verstetigen (Batching, Puffer), Caches zügeln, Limits realistisch setzen, Heap-Spitzen abflachen, Swap-Einfluss verringern. Ich messe gezielt vor und nach Änderungen, denn memory.some reagiert empfindlich auf Allokationsmuster.
  • I/O: Zugriffsprofile glätten (Batching, asynchrones I/O), Hotpaths entkoppeln, Prioritäten setzen, Queue-Tiefen passend wählen und konkurrierende Workloads entflechten. Ich bewerte Erfolge an sinkender io.pressure und kürzeren P99-Latenzen.

PSI im Teamalltag: Kommunikation und Ownership

Ich nutze PSI auch als gemeinsame Sprache zwischen Plattform- und Produktteams. Statt abstrakt über “langsam” zu sprechen, benenne ich die Ressource und das Muster: “io.some avg60 seit 20 Minuten über 4% bei Service X” oder “memory.full triggert in cgroup Y”. Diese Präzision erleichtert Priorisierung, weil klar ist, welche Owner handeln müssen und welches Budget (Zeit, Ressourcen) die größten Effekte verspricht. Über definierte Baselines vereinbare ich Qualitätsziele, die sowohl technisch belastbar als auch für Stakeholder verständlich sind.

Trigger, Baselines und schrittweises Rollout

Ich nutze PSI-Trigger mit Schwellwerten und Beobachtungsfenstern, damit ein Daemon automatisch reagiert, wenn Druck anhält. Für verlässliche Aussagen erstelle ich vor Änderungen eine Baseline über typische Lastphasen, die ich später mit neuen Messreihen vergleiche. Alerts definiere ich konservativ: some anhaltend erhöht gibt mir Zeit, full löst Gegenmaßnahmen aus. In großen Flotten rolle ich PSI-gestützte Alarme etappenweise aus, um Lärm zu vermeiden und Toleranzen sauber zu justieren. So bleibt mein Monitoring zielklar und belastbar, ohne Teams mit unnötigen Meldungen zu überziehen.

Nutzen für Hosting, Virtualisierung und Multi-Tenant

Ich sehe mit PSI, ob einzelne Workloads andere ausbremsen, ob Hardware-Reserven reichen und wo Limits nachgezogen werden müssen. In Shared-Umgebungen erkenne ich dauerhaft erzeugten CPU-, Speicher- oder I/O-Druck einzelner Accounts und plane Verlagerungen rechtzeitig. Cgroup-basierte Werte zeigen mir, welche Services betroffen sind und wo ich gezielt drossele oder priorisiere. So halte ich Antwortzeiten verlässlich und sorge für faire Ressourcennutzung auch unter Last. Das reduziert Kosten, verhindert Eskalationen und steigert die spürbare Qualität.

Abschluss: Aus Kennzahlen werden Entscheidungen

Ich setze Linux PSI ein, weil es Wartezeiten messbar macht und damit die Lücke zwischen Auslastung und Nutzererlebnis schließt. Mit some erkenne ich frühe Signale, mit full reagiere ich auf echte Blockaden, und mit Cgroups finde ich die genauen Verursacher. Dashboards, Trigger und Baselines verwandeln diese Sicht in konkrete Schritte: optimierte Limits, bessere Lastverteilung, saubere I/O-Pfade. Wer PSI aktiv nutzt, verkürzt die Zeit bis zur Ursache und spart sich viele blinde Tuning-Runden. So werden Monitoring-Daten zu klaren Entscheidungen, die Systeme spürbar schneller machen.

Aktuelle Artikel

Linux Server mit visualisierten Pressure Stall Information Kennzahlen im Rechenzentrum
Administration

Linux PSI für präzise Performanceanalyse und Monitoring

Linux PSI (Pressure Stall Information) macht sichtbar, wie stark CPU, Speicher und I/O dein System ausbremsen. Erfahre, wie du PSI aktivierst und für präzises Performance monitoring einsetzt.