tcpdump erhöht die Leistung von udp

13

Ich führe eine Reihe von Auslastungstests durch, um die Leistung des folgenden Setups zu bestimmen:

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

Kurz gesagt, die Testsuite node.js sendet alle x Sekunden eine festgelegte Anzahl von Metriken an eine StatsD-Instanz, die sich auf einem anderen Server befindet. StatsD spült dann die Metriken im Sekundentakt zu einer Graphite-Instanz, die sich auf demselben Server befindet. Ich schaue dann nach, wie viele Metriken tatsächlich von der Testsuite gesendet und wie viele von Graphite empfangen wurden, um den Paketverlust zwischen der Testsuite und Graphite zu bestimmen.

Ich bemerkte jedoch, dass ich manchmal sehr hohe Paket-Drop-Raten bekam (beachten Sie, dass es mit dem UDP-Protokoll gesendet wird), die zwischen 20 und 50% lagen. Zu diesem Zeitpunkt begann ich zu untersuchen, wo diese Pakete abgelegt wurden, da es sich um ein Leistungsproblem bei StatsD handeln könnte. Also begann ich, die Metriken in jedem Teil des Systems zu protokollieren, um herauszufinden, wo dieser Abfall auftrat. Und hier wird es komisch.

Ich verwende tcpdump , um eine Erfassungsdatei zu erstellen, die ich nach Abschluss des Tests überprüfe. Aber wenn ich die Tests mit laufendem tcpdump durchführe, ist der Paketverlust fast nicht vorhanden! Es sieht so aus, als würde tcpdump die Leistung meiner Tests irgendwie steigern, und ich kann nicht herausfinden, warum und wie dies geschieht. Ich führe den folgenden Befehl aus, um die tcpdump-Nachrichten sowohl auf dem Server als auch auf dem Client zu protokollieren:

tcpdump -i any -n port 8125 -w test.cap

In einem bestimmten Testfall sende ich 40000 Metriken / s. Der Test unter tcpdump hat einen Paketverlust von ca. 4%, während der Test ohne tcpdump einen Paketverlust von ca. 20% hat.

Beide Systeme werden als Xen-VMs mit folgendem Setup ausgeführt:

  • Intel Xeon E5-2630 v2 bei 2,60 GHz
  • 2 GB RAM
  • Ubuntu 14.04 x86_64

Dinge, die ich bereits auf mögliche Ursachen überprüft habe:

  • Erhöhen der Empfangs- / Sendegröße des UDP-Puffers.
  • CPU-Auslastung wirkt sich auf den Test aus. (maximale Auslastung von 40-50%, sowohl Client- als auch Serverseite)
  • Ausführen von tcpdump auf bestimmten Schnittstellen anstelle von "any".
  • Ausführen von tcpdump mit '-p', um den Promiscuous-Modus zu deaktivieren.
  • Ausführen von tcpdump nur auf dem Server. Dies führte zu einem Paketverlust von 20% und schien die Tests nicht zu beeinträchtigen.
  • Ausführen von tcpdump nur auf dem Client. Dies führte zu einer Leistungssteigerung.
  • Erhöhen von netdev_max_backlog und netdev_budget auf 2 ^ 32-1. Das machte keinen Unterschied.
  • Versuchte jede mögliche Einstellung des Promiscuous-Modus auf jedem NIC (Server an und Client aus, Server aus und Client an, beide an, beide aus). Das machte keinen Unterschied.
Ruben Homs
quelle
3
Tcpdump versetzt Ihre Netzwerkschnittstelle standardmäßig in den Promiscuous-Modus. Möglicherweise möchten Sie die -pOption überspringen, um festzustellen, ob dies einen Unterschied macht.
Zoredache
Sie führen tcpdump sowohl auf dem Client als auch auf dem Server aus und die Paketverlustrate sinkt? Was passiert, wenn Sie es nur auf dem Client ausführen, und was passiert, wenn Sie es nur auf dem Server ausführen? (Und ja, auch versuchen , die Promiscuous - Modus ausschalten, und versuchen Sie vielleicht auch auf dem spezifischen Netzwerk - Schnittstelle Erfassung für den Test verwendet , anstatt das „jeden“ Gerät, um zu sehen , ob das einen Unterschied macht.)
Danke für deine Kommentare. Ich habe beide Ihrer Empfehlungen ausprobiert und meine Frage bearbeitet, um zu reflektieren, was ich ausprobiert habe. Dies hatte jedoch keine Auswirkungen auf das Problem.
Ruben Homs
Hat das Versetzen von Netzwerkkarten auf beiden Computern in den Promiscuous-Modus den gleichen Effekt wie das Ausführen von tcpdump? Aktiviert ifconfig eth0 promiscund ifconfig eth0 -promiscdeaktiviert den Promiscuous-Modus auf eth0. Wenn es einen Unterschied macht, vergleichen Sie die 4 möglichen Kombinationen von Promisc-Ein / Aus auf beiden Computern. Dies könnte helfen, die Ursache der Probleme zu lokalisieren.
Fox
@ Fox Danke für die Antwort! Ich habe alle möglichen Kombinationen für alle Nics ausprobiert, aber ohne Unterschied in den Ergebnissen. Ich habe meine Frage aktualisiert, um dies widerzuspiegeln.
Ruben Homs

Antworten:

10

Wenn tcpdump ausgeführt wird, werden die eingehenden Frames ziemlich schnell eingelesen. Meine Hypothese ist, dass die Paketringpuffereinstellungen der Netzwerkkarte möglicherweise etwas zu klein sind. Wenn tcpdump ausgeführt wird, wird es schneller geleert.

Wenn Sie ein Red Hat-Abonnent sind, ist dieser Support-Artikel eine sehr nützliche Übersicht über den Paketempfang . Es sind einige Dinge drin, über die Sie, glaube ich, noch nicht nachgedacht haben.

Überlegen Sie, wie Ihr System mit IRQs umgeht. Ziehen Sie in Betracht, das 'dev_weight' der Netzwerkschnittstelle zu erhöhen (was bedeutet, dass mehr Pakete von der Netzwerkkarte in den Benutzerraum gelesen werden). Überprüfen Sie, wie oft die Anwendung den Socket liest (kann sie einen dedizierten Thread verwenden, sind Probleme / Problemumgehungen hinsichtlich der Skalierbarkeit bekannt?).

Erhöhen Sie den NIC-Frame-Puffer (verwenden Sie den ethtoolBefehl - sehen Sie sich die --set-ringArgumente usw. an).

Schauen Sie sich 'Receive Side Scaling' an und verwenden Sie mindestens so viele Empfangsthreads, um den Datenverkehr einzulesen.

Ich frage mich, ob tcpdump etwas cooles macht, wie die Kernelunterstützung für Paketringpuffer . Das würde helfen, das Verhalten zu erklären, das Sie sehen.

Cameron Kerr
quelle
Da dies eine Xen-Umgebung ist, sollten Sie dies wahrscheinlich (zumindest teilweise) auf dem Xen-Host tun.
Cameron Kerr
Das ist etwas, woran ich vorher nicht gedacht hatte, sehr interessantes Zeug, danke! Ich werde es versuchen, sobald ich Zugriff auf den Xen-Host habe, und Ihnen mitteilen, wie das geht.
Ruben Homs
2

Welchen Power Governor verwenden Sie? Ich habe ähnliche Verhaltensweisen mit "ondemand" oder "konservativem" Gouverneur gesehen.

Versuchen Sie, den "Leistungsregler" zu verwenden und alle Energiesparfunktionen im Server-BIOS zu deaktivieren.

Ändert es etwas?

Shodanshok
quelle
Ich habe Probleme herauszufinden, welchen Power Governor ich verwende. Ich habe versucht zu rennen cpufreq-info, bekomme aber eine Nachricht no or unknown cpufreq driver is active on this CPU. Auch bei Benutzung cpupower frequency-infokehrt es zurück no or unknown cpufreq driver is active on this CPU. Obwohl ich dies im Moment nicht bestätigen kann , glaube ich auf der Website des VM-Herstellers , dass es im "Performance" -Modus läuft, da ich eine Intel-CPU habe.
Ruben Homs
Können Sie die Ausgabe der folgenden Befehle anzeigen? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
Shodanshok
Los geht's
Ruben Homs
1

Ein anderer Weg ist das ip_conntarckModul. Sind Sie sicher, dass Ihre Linux-Box eine neue Verbindung akzeptieren kann? Test über:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Du musst testen

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

Wenn max == count ist, ist Ihre maximale Verbindung voll und Ihre Linux-Box kann keine neue Verbindung akzeptieren.
Wenn Sie ip_conntrack nicht haben, können Sie es einfach über ladenmodprobe ip_conntrack

Persischer Golf
quelle
2
Und wenn dies der Fall ist, sollten Sie das NOTRACK-Ziel in der 'raw'-Tabelle überprüfen, um zu verhindern, dass die Verbindung nachverfolgt wird. Ich habe das kürzlich für einen ausgelasteten DNS-Server gemacht und iptables aus dem Engpass entfernt, was zu Zeitüberschreitungen bei der DNS-Auflösung führte.
Cameron Kerr
Und hier ist ein Beispiel, wie ich die NOTRACK-Regeln verwendet habe, damit IPTables keine Verbindungsverfolgung für UDP-DNS durchführt. distracted-it.blogspot.co.nz/2015/05/…
Cameron Kerr
1

Ich vermute, die empfangende Seite ist einfach nicht in der Lage, die Paketrate zu handhaben, und hier ist der Grund:

  1. Durch die Verwendung von tcpdump auf dem Client werden die verworfenen Pakete reduziert: tcpdump verlangsamt den Client, und daher sieht der Server eine viel niedrigere Packer-Rate, die er teilweise noch verarbeiten kann. Sie sollten in der Lage sein, diese Hypothese zu bestätigen, indem Sie die RX / TX-Paketzähler sowohl auf dem Client als auch auf dem Server überprüfen

  2. Sie haben erwähnt, dass Sie die Empfangs- / Sendegröße des UDP-Puffers erhöht haben. Können Sie genauer erläutern, wie? Es ist wichtig, dass Sie auf dem Server sowohl rmem_max als auch rmem_default ändern. Beispiel: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

Testen Sie Ihre Einstellungen

Stoppen Sie statsd und die Node-Anwendung, und testen Sie im Leerlauf des Systems mit iperf die Paketrate , die das Netzwerk / der Kernel verarbeiten kann. Wenn Sie 40K-Pakete / s mit iperf streamen können, aber nicht mit statsd, sollten Sie sich auf die Optimierung von statsd konzentrieren.

Andere Tunables

Denken Sie auch daran, net.core.netdev_max_backlog zu optimieren : Maximale Anzahl von Paketen, die in die Warteschlange gestellt werden dürfen, wenn eine bestimmte Schnittstelle Pakete schneller empfängt, als der Kernel sie verarbeiten kann.

unicoletti
quelle