Warum ist mein TCP-Durchsatz viel größer als der UDP-Durchsatz?

15

Ich habe nichts Ungewöhnliches an meiner Hardware- oder Kernelkonfiguration gemacht (alle Standardeinstellungen, Neuinstallation des Betriebssystems, Linux-Kernel 3.11 TCP / IP-Stack) und durchschnittlich 3,83 Millionen Nachrichten pro Sekunde über TCP, während ich nur einen Durchschnitt von 0,75 habe Millionen Nachrichten pro Sekunde über UDP. Dies scheint völlig zu trotzen, was ich von den beiden Protokollen erwarte.

Was ist die wahrscheinlichste Ursache für den drastischen Unterschied und wie kann ich ihn unter Ubuntu 13.10 diagnostizieren?

#TCP RESULTS
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

87380  65536     64    10.00      1963.43   32.96    17.09    5.500   2.852

#UDP RESULTS
Socket  Message  Elapsed      Messages                   CPU      Service
Size    Size     Time         Okay Errors   Throughput   Util     Demand
bytes   bytes    secs            #      #   10^6bits/sec % SS     us/KB

4194304      64   10.00     7491010      0      383.5     28.97    24.751
212992            10.00     1404941              71.9     25.03    21.381

Für diesen Test habe ich zwei Testserver, die identisch und direkt über ein 10G-Crossover-Kabel verbunden sind. Die in diesem Fall verwendeten NICs sind Intel X520 mit werkseitigen Konfigurationen und werden an einen PCIe 3.0 x8-Steckplatz auf der Hauptplatine angeschlossen, der über einen NUMA-Controller mit der CPU kommuniziert.

elleciel
quelle
Wie hast du die Benchmarks? Gegen was hast du diese Pakete geschickt?
Braiam
Ich habe netperffür die Benchmarks UDP_STREAM- und TCP_STREAM-Tests verwendet, die auf dieselbe CPU und 64-Byte-Nachrichtengrößen festgelegt sind.
Elleciel
1
Das beantwortet @ Braiam's Frage nicht. Hier ist die Netzwerktopologie und eine detaillierte Testmethode wichtig.
Pavel Šimerda
1
@ PavelŠimerda Sorry, ich dachte er fragt nur nach der Testmethode. In Bezug auf die Netzwerktopologie sind die beiden Testserver identisch und direkt über ein 10G-Crossover-Kabel verbunden. Die in diesem Fall verwendeten NICs sind Intel X520 mit werkseitigen Konfigurationen und werden an einen PCIe 3.0 x8-Steckplatz auf der Hauptplatine angeschlossen, der über einen NUMA-Controller mit der CPU kommuniziert. Beantwortet das deine Frage?
Elleciel
1
Ja, @elleciel, es beantwortet definitiv meine Frage. Obwohl ich in diesem Fall nicht die Expertise habe, Ihnen die Antwort für direkt angeschlossene Maschinen zu geben. Ich sehe, dass Sie die Frage selbst geändert haben, was großartig ist. Werde mal die Frage stellen wie mich jetzt auch interessiert.
Pavel Šimerda

Antworten:

29

Abgesehen davon, dass Sie keine detaillierten Informationen zu Ihrem Testaufbau erhalten, scheint das Hauptproblem darin zu liegen, dass Sie eine Nachrichtengröße von 64 Byte verwenden. Dies ist weit entfernt von der üblichen MTU von 1500 Bytes und macht UDP sehr ineffizient: Während TCP mehrere Sends in einem einzigen Paket auf der Leitung zusammenführt (außer wenn TCP_NODELAY festgelegt ist), um die Verbindung effizient zu nutzen, führt jede UDP-Nachricht zu ein separates Paket. In Zahlen: Etwa 23 Nachrichten mit einer Größe von 64 Byte werden zu einem einzelnen TCP-Paket mit MTU-Größe kombiniert, während für UDP 23 einzelne Pakete für dieselbe Datenmenge benötigt werden. Jedes dieser Pakete bedeutet Overhead beim Senden vom Host, Senden auf der Leitung und Empfangen durch den Peer. Und wie in Ihrem Fall zu sehen ist, gehen ungefähr 80% der UDP-Pakete verloren, da Ihre Hardware nicht schnell genug ist, um all diese Pakete zu senden und zu empfangen.

Was Sie also aus diesem Benchmark lernen können, ist:

  • UDP ist unzuverlässig (80% Paketverlust)
  • UDP ist ineffizient, wenn es mit Paketgrößen weit unter MTU verwendet wird
  • TCP ist stark optimiert, um die Verbindung optimal zu nutzen

Was Ihre Erwartung betrifft, sollte UDP besser sein: Haben Sie sich jemals gefragt, warum alle wichtigen Dateiübertragungen (ftp, http, ...) mit TCP-basierten Protokollen durchgeführt werden? Der Benchmark zeigt Ihnen den Grund.

Warum wird UDP überhaupt verwendet?

  • Bei Echtzeitdaten (z. B. Voice over IP) interessieren Sie sich nicht für ältere Nachrichten. Sie möchten daher nicht, dass der Absender Nachrichten zu größeren Paketen kombiniert, um die Verbindung effektiv zu nutzen. Und Sie akzeptieren eher, dass ein Paket verloren geht, als dass es zu spät ankommt.
  • Bei Verbindungen mit hoher Latenz (wie bei Satelliten) ist das Standardverhalten von TCP nicht optimal, um die Verbindung effektiv zu nutzen. In diesem Fall stellen einige Benutzer auf UDP um und implementieren die Zuverlässigkeitsschicht von TCP erneut und optimieren sie für Verbindungen mit hoher Latenz, während andere den vorhandenen TCP-Stack optimieren, um die Verbindung besser zu nutzen.
  • Daten "wegwerfen": Manchmal ist es wichtiger, die Daten wegzuschicken und sich nicht um Paketverluste zu kümmern, wie bei Protokollnachrichten (Syslog).
  • Kurze Interaktionen: Bei TCP müssen Sie eine Verbindung herstellen und einen Zustand aufrechterhalten, der Zeit und Ressourcen auf Client und Server kostet. Für kurze Interaktionen (wie kurze Anfragen und Antworten) ist dies möglicherweise zu viel Aufwand. Aus diesem Grund wird DNS normalerweise mit UDP ausgeführt, hat jedoch Wiederholungsversuche über UDP erstellt.
Steffen Ullrich
quelle
2
Sie sollten sich auch Ihren 80% igen Paketverlust bei UDP ansehen. Es sieht so aus, als ob Ihre Hardware nicht schnell genug ist, um die Pakete mit der gleichen Geschwindigkeit zu verarbeiten, mit der sie gesendet werden. Während sich TCP mit einer Verlangsamung an diese Art von Paketverlust anpasst, sendet UDP nur mit derselben Geschwindigkeit und verliert weiterhin Pakete. Aber am Ende ist es nicht wichtig, wie schnell Sie senden können, sondern was Sie empfangen.
Steffen Ullrich
1
Ein weiterer möglicher Faktor ist die TCP-Beschleunigung / das Auslagern auf die Netzwerkkarte (sofern dies unterstützt wird).
cpugeniusmv
1
Das Senden von Paketen ist möglicherweise effizienter als das Empfangen, insbesondere wenn das letzte unterbrechungsgesteuert ist.
Steffen Ullrich
1
Leute verwenden UDP auch für ein eingebettetes Gerät, um die Daten, die es sammelt, über eine Leitung zu verbreiten, und kümmern sich nicht um den Verbindungsaufbau
Ratschenfreak
3
Sie sind höchstwahrscheinlich an den PCI-Express-Bus gebunden. Bei den Netzwerkkarten ist höchstwahrscheinlich das TCP-Segment-Offloading aktiviert. Dies bedeutet, dass TCP-Übertragungen als ein großer Block an die Karte gesendet werden, dann schneidet und schneidet die Karte sie in Pakete und legt sie auf die Leitung. Für UDP gibt es keine Entsprechung. Das Ergebnis ist eine PCIe-Transaktion (und alle damit verbundenen Overheads) für jedes Paket.
alex.forencich