Empfangsverluste zwischen NIC, Softirq und Netzwerkstack eingrenzen

Empfangsverluste zwischen NIC, Softirq und Netzwerkstack eingrenzen

Empfangsverluste zwischen NIC, Softirq und Netzwerkstack eingrenzen

Wenn Anfragen sporadisch in ein Timeout laufen und zugleich die Zähler für verworfene Empfangspakete steigen, muss nicht die Netzwerkkarte defekt sein. Der Empfangspfad eines Dedicated Servers umfasst NIC-Warteschlangen, Treiber, Softirqs und den Netzwerkstack. Dasselbe Symptom kann auf unterschiedlichen Ebenen entstehen. Entscheidend ist, Anwendungsfehler mit den Zählerdifferenzen desselben Zeitfensters abzugleichen – nicht bei jedem Auftreten von dropped pauschal alle Puffer zu vergrößern.

Die folgenden Beispiele verwenden Debian 12 und setzen Administratorrechte sowie die Werkzeuge iproute2, ethtool, sysstat und python3 voraus. Bei einem Dedicated Server von AmdMetal sind die Zugangsdaten nach der Zahlung in der Konsole einsehbar; für SSH wird die erste IPv4-Adresse verwendet. Zunächst werden ausschließlich lesende Messungen durchgeführt. Adressen und Routen bleiben unverändert.

1. Empfangsschnittstelle und Störungszeitfenster bestimmen

Ermitteln Sie zunächst mit ip -br address, welcher Schnittstelle die für die Anwendung verwendete Adresse zugeordnet ist. Verfolgen Sie anschließend gegebenenfalls VLANs, Bridges oder Bonding-Geräte bis zur physischen Schnittstelle, die den Datenverkehr tatsächlich transportiert. Wählen Sie nicht einfach die alphabetisch erste Netzwerkkarte. Im folgenden Beispiel wird die Schnittstelle interaktiv eingegeben; das Verzeichnis für die Messdaten wird automatisch angelegt:

read -r -p "Physical interface: " IFACE
ip link show dev "$IFACE" || exit 1
D=$(mktemp -d /var/tmp/rx-audit.XXXXXX)
printf '%s\n' "$IFACE" > "$D/interface"
uname -r > "$D/kernel"
ethtool -i "$IFACE" > "$D/driver"
ip -d link show dev "$IFACE" > "$D/link"
printf '%s\n' "$D"

Notieren Sie den Zeitpunkt der Anwendungsfehler, die Anzahl der Anfragen, die Paketgrößen und ob ein Massenimport stattgefunden hat. Kumulierte Schnittstellenzähler können einen sehr langen Betriebszeitraum abdecken. Aus ihnen lässt sich kein unmittelbarer Zusammenhang mit einem gerade aufgetretenen Timeout ableiten. Auch das Neuladen des Treibers, ein Neustart oder das Neuerstellen der Schnittstelle kann Zähler zurücksetzen.

NIC-, Schnittstellen- und Netzwerkstack-Statistiken sind keine voneinander unabhängigen Größen, die sich einfach addieren lassen. Manche Felder können dasselbe Ereignis erfassen. Prüfen Sie deshalb zuerst die Definitionen des Treibers, bevor Sie die Zählerdifferenzen interpretieren.

Läuft die Anwendung in einem Netzwerk-Namespace, zeigt die physische Schnittstelle den Empfangspfad des Hosts. Die Statistiken des Netzwerkstacks müssen zusätzlich im Namespace der Anwendung erfasst werden. Fehlerfreie Host-Statistiken bedeuten nicht, dass innerhalb des Containers alles ordnungsgemäß funktioniert.

2. Schnittstellen- und Treiberstatistiken gemeinsam erfassen

Führen Sie die folgenden Befehle in derselben Shell aus. Das Beobachtungsfenster beträgt im Beispiel 30 Sekunden. Dies ist ein Messparameter, keine Leistungszusage. Wählen Sie eine Phase, in der das Problem tatsächlich auftritt, und erfassen Sie zum Vergleich auch ein gleich langes Zeitfenster ohne Störung.

snapshot() {
    label=$1
    date -Is > "$D/$label.time"
    ip -s -s link show dev "$IFACE" > "$D/$label.link"
    ethtool -S "$IFACE" > "$D/$label.nic" 2>&1
    cat /proc/net/softnet_stat > "$D/$label.softnet"
    nstat -az > "$D/$label.protocol"
}
snapshot before
mpstat -P ALL 1 30 > "$D/cpu"
snapshot after
diff -u "$D/before.nic" "$D/after.nic"

Diese Abfragen erfolgen nacheinander und bilden keinen atomaren Snapshot. Bei kurzen Lastspitzen müssen die Zeitstempel in die Auswertung einfließen; eine paketgenaue Übereinstimmung zwischen den Dateien ist nicht zu erwarten. Meldet ethtool -S, dass die Abfrage nicht unterstützt wird, bewahren Sie diese Ausgabe auf. „Keine Statistiken verfügbar“ darf nicht als „keine Paketverluste“ ausgelegt werden.

Zuerst die Bedeutung der Zähler prüfen

Steigen Fehlerzähler mit CRC oder frame im Namen, sollten Sie nach Hinweisen auf Probleme der Sicherungsschicht suchen. Bei Feldern mit missed, no_buffer oder discard ist die Definition des aktuell verwendeten Treibers maßgeblich. Diese Zähler können sich auf Empfangsdeskriptoren, Gerätepuffer oder Filtervorgänge beziehen. Aus dem englischen Namen allein lässt sich die Ursache nicht bestimmen.

Speichern Sie außerdem die Ausgaben von ethtool -g "$IFACE" und ethtool -l "$IFACE", um Informationen zu Ringpuffern beziehungsweise Kanälen zu erhalten. Werden diese Abfragen nicht unterstützt, ist das für sich genommen kein Fehler. Angegebene Maximalwerte beschreiben lediglich die Grenzen der Gerätefähigkeiten und sind keine Empfehlungen für den Produktivbetrieb.

3. Softnet-Differenzen pro CPU berechnen

Die Werte in /proc/net/softnet_stat sind hexadezimal. Die ersten drei Spalten stehen in dieser Reihenfolge für processed, dropped und time_squeeze. Die nachfolgenden Spalten können je nach Kernel variieren und werden hier nicht ausgewertet. Das folgende Skript vergleicht die Einträge zeilenweise und gibt die jeweilige Zeilennummer aus. Bei CPU-Hotplug muss die Messung wiederholt werden; die Zeilen dürfen dann nicht ungeprüft weiter einander zugeordnet werden.

python3 - "$D/before.softnet" "$D/after.softnet" <<'PY'
import sys
from pathlib import Path

def load(path):
    return [
        [int(v, 16) for v in line.split()[:3]]
        for line in Path(path).read_text().splitlines()
    ]

before, after = map(load, sys.argv[1:])
if len(before) != len(after):
    raise SystemExit("CPU layout changed; sample again")

print("row processed_delta dropped_delta time_squeeze_delta")
for row, (old, new) in enumerate(zip(before, after)):
    delta = [b - a for a, b in zip(old, new)]
    if any(v < 0 for v in delta):
        raise SystemExit("Counter reset or wrap; sample again")
    print(row, *delta)
PY

Ein Anstieg von dropped weist hier auf verworfene Pakete in der Software-Empfangswarteschlange hin. Ein Anstieg von time_squeeze bedeutet dagegen, dass ein Verarbeitungsdurchlauf seine Budgetgrenze erreicht hat – nicht, dass bereits Pakete verloren gegangen sind. Softnet-Statistiken werden pro CPU zusammengefasst und sind keiner einzelnen Netzwerkkarte exklusiv zugeordnet. Gleichzeitig anfallender Datenverkehr anderer Schnittstellen muss daher als Ursache ausgeschlossen werden.

Vergleichen Sie die Differenzen mit %soft aus mpstat. Auch wenn der Server insgesamt freie CPU-Kapazität hat, kann ein einzelner Kern durch die Empfangsverarbeitung stark belastet sein. Die durchschnittliche Auslastung allein reicht deshalb nicht aus. Speichern Sie bei Bedarf /proc/interrupts und prüfen Sie, ob sich die Interrupts der NIC-Warteschlangen auffällig konzentrieren. Die Interrupt-Verteilung liefert jedoch nur einen Anhaltspunkt; eine Gleichverteilung ist kein zwingendes Abnahmekriterium.

4. Die Anpassungsebene anhand der Befunde wählen

Steigen missed-artige NIC-Zähler, während softnet dropped unverändert bleibt, prüfen Sie zuerst den Empfangsring und die Treiberwarteschlangen. Steigt dagegen softnet dropped zusammen mit einer hohen Belastung einzelner Kerne, sollten Sie die Software-Empfangswarteschlange und die Verteilung des Datenverkehrs untersuchen. Bleiben beide Zählergruppen stabil, vergleichen Sie als Nächstes die Zuwächse der Protokollfehler in nstat mit den Anwendungsprotokollen, statt die Netzwerkkarte weiter auf Verdacht zu optimieren.

Sichern Sie vor Änderungen die aktuelle Konfiguration:

ethtool -g "$IFACE" > "$D/rings" 2>&1
ethtool -l "$IFACE" > "$D/channels" 2>&1
sysctl net.core.netdev_max_backlog \
       net.core.netdev_budget \
       net.core.netdev_budget_usecs > "$D/budgets"

Eine Änderung der Ringgröße kommt nur infrage, wenn der Treiber sie unterstützt und die Befunde dafür sprechen. „Auf den Maximalwert setzen“ ist keine allgemeingültige Lösung. Eine größere Empfangswarteschlange kann weniger verworfene Pakete mit höheren Wartezeiten erkaufen. Ein höheres Verarbeitungsbudget kann der Anwendung CPU-Zeit entziehen. Änderungen an der Verteilung über mehrere Warteschlangen müssen außerdem IRQ, RSS und die Anzahl der Anwendungsdatenströme berücksichtigen. Ein einzelner Datenstrom verteilt sich dadurch nicht automatisch auf alle Kerne.

Über eine Remote-Verbindung sollten Sie weder eine Neukonfiguration der Kanäle noch das Neuladen des Treibers oder einen Link-Reset unvorbereitet ausprobieren. Diese Eingriffe können SSH beeinträchtigen. Bereiten Sie zuvor einen kontrollierten Ablauf, eine Aufzeichnung der Ausgangswerte und einen Wiederherstellungsweg vor. Ändern Sie pro Durchlauf nur eine Einstellung und stellen Sie bei Problemen zuerst den ursprünglichen Wert wieder her.

5. Die Wirkung mit einem erneuten Anwendungstest bestätigen

Halten Sie beim erneuten Test Anfragetypen, Laufzeit und Parallelität vergleichbar und erfassen Sie gleichzeitig den tatsächlichen Datenverkehr. Wer nur die absolute Anzahl verworfener Pakete in zwei Zeitfenstern vergleicht, kann eine gesunkene Last irrtümlich als erfolgreiche Optimierung werten. Auch bei gleichem Durchsatz kann die Empfangsverarbeitung unterschiedlich stark belastet sein, wenn mehr kleine Pakete anfallen.

Die Abnahme sollte mindestens drei Ergebnisgruppen umfassen:

Bleiben die Zähler der unteren Ebenen stabil, während weiterhin Anwendungsfehler auftreten, sollte die Schlussfolgerung lauten: „Im untersuchten Zeitfenster wurden keine entsprechenden Hinweise auf verworfene Empfangspakete gefunden.“ Untersuchen Sie anschließend den Netzwerkstack und die Verarbeitung in der Anwendung weiter, statt das Netzwerk pauschal für vollständig fehlerfrei zu erklären. Bewahren Sie Angaben zu Schnittstelle, Treiber und Kernel sowie die Messdateien und die ursprünglichen Werte geänderter Einstellungen auf. Nur so lässt sich die vermutete Ursachenkette beim nächsten Auftreten desselben Symptoms erneut überprüfen.

Häufig gestellte Fragen

Beweist ein steigender dropped-Zähler in ip -s link einen NIC-Defekt?

Nein. Der Sammelzähler muss mit Treiberstatistik, Leitungsfehlern und Anwendungssymptomen desselben Zeitfensters abgeglichen werden. Alle Zähler mit drop im Namen ungeprüft zu addieren ist nicht sinnvoll.

Bedeutet ein Anstieg von time_squeeze bereits Paketverlust?

Nicht allein. Der Zähler zeigt eine erreichte Budgetgrenze bei der Empfangsverarbeitung an. Zusätzlich sind dropped-Differenzen, Softirq-Last je CPU und Anwendungsfehler zu prüfen.

AMD EPYC 7543P Dedicated Server

ab $458.7/Monat

AMD EPYC 7543P Server konfigurieren Mietpreise für Dedicated Server ansehen

Serverkonfiguration im Detail

Der AMD EPYC 7543P steht exklusiv als Komplettsystem bereit; Modell und Optionen werden auf der Konfigurationsseite zusammengestellt.