CFS: Completely Fair Scheduler Deep Dive (Artikel 379)
Tiefgehende Analyse des Completely Fair Scheduler (CFS). Erfahren Sie alles über virtuelle Laufzeiten, Red-Black Trees und wie der Linux-Kernel Rechenzeit absolut gerecht verteilt.
# CFS Masterclass: Die Mathematik der Fairness im Kernel
TL;DR / Management Summary Der Completely Fair Scheduler (CFS) ist seit Kernel 2.6.23 der Standard-Algorithmus für die Prozessverwaltung. Er bricht mit der Tradition der festen Zeitscheiben. Stattdessen nutzt er ein hocheffizientes Modell basierend auf virtuellen Laufzeiten (vruntime) und Red-Black Trees. Ein Senior Admin muss die Mechanik verstehen, um das Antwortverhalten (Latenz) gegen den Durchsatz abzuwägen und komplexe Multi-Core-Engpässe zu diagnostizieren.
# 1. Einführung & Architektur
Weg von der festen Zeitscheibe.
Frühere Scheduler gaben jedem Prozess z.B. 10ms. Wer fertig war, war fertig. Wer nicht, musste warten. CFS hingegen versucht, eine “ideale, perfekte Multi-Tasking-Maschine” zu simulieren.
# Der Datenstruktur-Kern (Mermaid)
graph TD
A[CFS Runqueue] --> B{Red-Black Tree}
B --> C[Leftmost Node: Smallest vruntime]
B --> D[Center Nodes]
B --> E[Rightmost Node: Largest vruntime]
C --> F[SELECTED: Next task to run]
subgraph "The Math"
G[Weight based on Nice]
H[Delta execution time]
G/H --> I[Update vruntime]
end
I --> B
# 2. vruntime: Die einzige Metrik, die zählt
Wer hat am wenigsten bekommen?
Der Kernel führt Buch darüber, wie lange jeder Prozess bereits auf der CPU war. Dieser Wert wird als vruntime gespeichert.
- Logik: Der Prozess mit der kleinsten
vruntimedarf als Nächstes auf die CPU. - Nice-Werte: Ein niedriger Nice-Wert (hohe Prio) sorgt dafür, dass die
vruntimelangsamer steigt. Der Prozess darf also länger rechnen, bevor er “unfair” gegenüber anderen wird.
# 3. Die Hebel des Admins
Den Scheduler zur Laufzeit tunen.
Nutzen Sie sysctl, um das Verhalten des CFS anzupassen.
# 1. Granularität vs. Latenz
# Minimale Zeit, die ein Prozess rechnen darf, bevor er unterbrochen werden kann
# (Standard: oft 0.75ms bis 3ms)
sudo sysctl -w kernel.sched_min_granularity_ns=3000000
- Hoher Wert: Weniger Kontext-Wechsel (besser für Durchsatz/Datenbanken).
- Niedriger Wert: Höhere Reaktivität (besser für Desktop/Audio).
# 2. Migration Cost
Wie teuer ist es, einen Prozess von einem Kern auf einen anderen zu schieben?
sudo sysctl -w kernel.sched_migration_cost_ns=500000
# 4. Day-2 Operations: Monitoring
Dem Scheduler bei der Arbeit zusehen.
# Scheduler-Statistiken
# Detaillierte Infos pro CPU-Kern
cat /proc/sched_debug
# Prozess-Sicht
# Zeigt Scheduler-Details für eine spezifische PID
cat /proc/<PID>/sched
Achten Sie auf se.vruntime und nr_switches.
# 5. Troubleshooting & “War Stories”
Wenn die Fairness zur Last wird.
# Story 1: “Der Jitter in der Echtzeit-App”
Symptom: Eine Mess-Applikation hat unregelmäßige Latenz-Spikes (Jitter), obwohl die CPU-Last niedrig ist.
Ursache: Der CFS versucht fair zu sein und unterbricht die App alle paar Millisekunden, um andere (unwichtige) Hintergrund-Prozesse kurz rechnen zu lassen.
Lösung: Nutzen Sie Real-Time Policies (Artikel 370) oder erhöhen Sie sched_min_granularity_ns, um Unterbrechungen zu minimieren.
# Story 2: “Das Load-Rätsel bei 100% CPU”
Symptom: top zeigt 100% CPU-Last, aber die Load-Average liegt bei 50.0 (bei 8 Kernen).
Ursache: “Runqueue Contention”. Zu viele Prozesse haben eine ähnliche vruntime und kämpfen um die gleichen Kerne. Der Scheduler verbringt mehr Zeit mit dem Verwalten des Baums als mit echtem Rechnen.
Lösung: Prüfen Sie sched_latency_ns. Falls zu viele Prozesse gleichzeitig aktiv sind, hilft oft nur eine Verteilung auf mehrere Server oder das Begrenzen via Cgroups (Artikel 375).
# 6. Fazit & Empfehlung
- Verständnis: CFS ist kein Feind, sondern der Grund für die Stabilität von Linux unter Hochlast.
- Tuning: Ändern Sie Scheduler-Parameter nur, wenn Sie exakte Benchmarks haben. Die Defaults sind für 99% der Workloads exzellent.
- Wahl: Nutzen Sie CPU Pinning (Artikel 370), wenn Sie die Auswirkungen des Schedulers komplett eliminieren wollen.
# Anhang: Cheatsheet
| Aufgabe | Pfad / Befehl |
|---|---|
| Global Debug | cat /proc/sched_debug |
| Pro Prozess Info | cat /proc/<pid>/sched |
| Latenz-Intervall | kernel.sched_latency_ns |
| Min. Granularität | kernel.sched_min_granularity_ns |
| Wakeup Granularität | kernel.sched_wakeup_granularity_ns |
| Scheduler Features | cat /sys/kernel/debug/sched_features |
| Context Switches | vmstat 1 (Spalte cs) |
| Latency Audit | perf sched latency |