Wenn Dein Server nur laggt, wenn Du nicht hinschaust: IRQ-Imbalance beheben
Wenn Dein Server nur laggt, wenn Du nicht hinschaust: IRQ-Imbalance beheben
TL;DR: Mein Proxmox-Server hatte mysteriöse Netzwerk-Lags, die verschwanden, sobald ich htop öffnete. Alle Netzwerk-Interrupts wurden von einem einzigen CPU-Kern verarbeitet. Nach Aktivierung von irqbalance, RPS-Tuning und Anpassung der Netzwerk-Buffer war das Lag endgültig weg. Hier erfährst du, wie du IRQ-Imbalance auf deinem eigenen Server diagnostizierst und behebst.
Der Observer-Effect-Bug
Kennst du das Gefühl, wenn dein Auto wochenlang komische Geräusche macht, aber in dem Moment, wo du es zur Werkstatt fährst, läuft es perfekt? So war es letzten Monat mit meinem Proxmox-Server.
Die Symptome:
- Zufällige Netzwerk-Lag-Spitzen (200-500ms Ping-Sprünge)
- Container-Webservices, die gelegentlich timeouts hatten
- SSH-Sessions, die zufällig für 2-3 Sekunden einfroren
- Der Hammer: In dem Moment, wo ich per SSH eingeloggt war und
htopoder Netdata öffnete, lief alles smooth
Das ist die frustrierendste Art von Bug - einer, der sich versteckt, sobald man versucht, ihn zu beobachten. Schrödingers Lag sozusagen.
💡 Tipp: Das ist keine Magie. Wenn du Monitoring-Tools startest, erzeugen sie Prozesse auf verschiedenen CPU-Kernen, was temporär die Workload verschiebt und dem überlasteten Kern eine Verschnaufpause gibt.
Voraussetzungen
Bevor wir loslegen, brauchst du:
- Einen Linux-Server (ich nutze Proxmox, aber das funktioniert auf jedem Debian/Ubuntu-basierten System)
- Root-Zugriff
- Grundlegende Kommandozeilen-Kenntnisse
- Etwa 30 Minuten für Diagnose und Fixes
- Geduld (bei einigem davon muss man Zählern beim Hochzählen zusehen)
Schritt 1: Zuerst Security-Check
Wenn plötzlich merkwürdige Performance-Probleme auftauchen, ist mein erster Gedanke immer: “Hat sich jemand eingehackt?”
# Nach verdächtigen Prozessen suchen
ps aux | grep -iE 'xmr|crypto|mine'
# Nach unauthorisierten SSH-Keys suchen
cat ~/.ssh/authorized_keys
# Auf Rootkits prüfen
apt install -y chkrootkit rkhunter
chkrootkit
rkhunter --check --skip-keypress
# Laufende Netzwerkverbindungen überprüfen
netstat -tulpn | grep ESTABLISHED
Alles war sauber. Keine Crypto-Miner, keine verdächtigen Prozesse, kein unautorisierter Zugriff.
⚠️ Warnung: Überspringe diesen Schritt niemals. Performance-Probleme können Symptome einer Kompromittierung sein.
Schritt 2: Die IRQ-Imbalance entdecken
Was sind IRQs überhaupt?
IRQ (Interrupt Request) ist die Art, wie Hardware-Geräte (wie deine Netzwerkkarte) die Aufmerksamkeit der CPU bekommen. Wenn ein Netzwerkpaket ankommt, sagt die NIC “Hey CPU, ich hab was für dich!” via Interrupt.
# Interrupt-Verteilung in Echtzeit beobachten
watch -n 2 'cat /proc/interrupts | grep -E "CPU|eth0|eno1|enp"'
💡 Tipp: Ersetze
eth0odereno1mit deinem tatsächlichen Netzwerk-Interface-Namen. Finde ihn mitip link show.
Das habe ich gesehen:
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 ...
eth0-TxRx 3301245 0 0 0 0 0 ...
Autsch. Alle 3,3 Millionen Interrupts nur auf CPU0. Jedes einzelne Netzwerkpaket von einem Kern verarbeitet, während die anderen 11 Kerne rumchillten.
Softirqs checken
watch -n 2 'cat /proc/softirqs | grep -E "CPU|NET_RX"'
CPU0 verarbeitete 10x mehr Receive-Softirqs als andere Kerne. Das war die rauchende Waffe.
Schritt 3: Der Fix (Mehrere Schichten)
Schicht 1: irqbalance installieren
apt install -y irqbalance
systemctl enable --now irqbalance
systemctl status irqbalance
Schicht 2: RPS aktivieren (Receive Packet Steering)
# Finde deinen Interface-Namen
ip link show
# RPS für alle CPUs aktivieren (passe den Hex-Wert an deine CPU-Anzahl an)
# fff = 12 CPUs in hex, f = 4 CPUs, ff = 8 CPUs, ffff = 16 CPUs
echo "fff" > /sys/class/net/eth0/queues/rx-0/rps_cpus
Wie man die RPS-Maske berechnet:
- Zähle deine CPU-Kerne:
nproc - Konvertiere zu hex: 4 CPUs =
f, 8 =ff, 12 =fff, 16 =ffff
Schicht 3: NIC Ring-Buffer erhöhen
# Aktuelle Größe checken
ethtool -g eth0
# Auf Maximum erhöhen
ethtool -G eth0 rx 4096 tx 4096
Schicht 4: Network-Stack tunen (sysctl)
Erstelle /etc/sysctl.d/99-network-tuning.conf:
# Socket-Buffer-Größen erhöhen (128MB)
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
# TCP-Buffer Auto-Tuning
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
# Network-Device-Backlog-Queue erhöhen
net.core.netdev_max_backlog = 5000
# Softirq-Processing-Budget erhöhen
net.core.netdev_budget = 600
Anwenden:
sysctl -p /etc/sysctl.d/99-network-tuning.conf
Schritt 4: Persistent machen
Erstelle /etc/systemd/system/network-tuning.service:
[Unit]
Description=Network Performance Tuning
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
# Ersetze eth0 mit deinem Interface-Namen und fff mit deiner CPU-Maske
ExecStart=/bin/bash -c 'echo "fff" > /sys/class/net/eth0/queues/rx-0/rps_cpus'
ExecStart=/usr/sbin/ethtool -G eth0 rx 4096 tx 4096
[Install]
WantedBy=multi-user.target
Aktivieren:
systemctl daemon-reload
systemctl enable network-tuning.service
systemctl start network-tuning.service
Schritt 5: Den Fix verifizieren
# Interrupt-Verteilung überwachen
watch -n 2 'cat /proc/interrupts | grep -E "CPU|eth0"'
# Auf Paket-Drops checken
netstat -s | grep -iE 'drop|prune|collapse'
# Softirq-Verteilung beobachten
watch -n 2 'cat /proc/softirqs | grep -E "CPU|NET_RX"'
Fehler, die ich gemacht habe
- Habe Security nicht zuerst gecheckt: Immer zuerst Security checken.
- Falsche RPS-Maske verwendet: Mit
nprocchecken! - Vergessen, Settings persistent zu machen: Immer den systemd-Service erstellen.
- Habe vorher/nachher nicht überwacht: Immer den “Vorher”-Zustand dokumentieren.
Was ich gelernt habe
- irqbalance sollte Standard sein auf jedem Server mit echtem Traffic
- Der “Observer-Effect” ist keine Magie - es ist der Scheduler unter Last
- Netzwerk-Tuning ist ein Stack - Hardware-IRQs, RPS, Buffer, sysctl arbeiten zusammen
- Moderne NICs brauchen moderne Settings - 256-Paket-Buffer sind zu klein für Gigabit
Rollback (falls nötig)
systemctl stop network-tuning.service
systemctl disable network-tuning.service
ethtool -G eth0 rx 256 tx 256
rm /etc/sysctl.d/99-network-tuning.conf
sysctl -p
systemctl stop irqbalance
systemctl disable irqbalance
reboot
Ressourcen
Update 2025-12-11: Erstveröffentlichung