webentwicklung-frage-antwort-db.com.de

Wann sollte ich TCP_NODELAY und wann TCP_CORK verwenden?

Ich habe verstanden, dass beide Nagles Algorithmus deaktivieren.

Wann sollte/sollte ich nicht jeden von ihnen benutzen?

57
user360455

Erstens deaktivieren nicht beide den Nagle-Algorithmus.

Nagles Algorithmus dient dazu, mehr kleine Netzwerkpakete im Kabel zu reduzieren. Der Algorithmus lautet: Wenn die Daten kleiner als ein Limit sind (normalerweise MSS), warten Sie, bis Sie ACK für zuvor gesendete Pakete erhalten, und sammeln Sie in der Zwischenzeit Daten vom Benutzer. Dann senden Sie die gesammelten Daten.

if [ data > MSS ]
    send(data)
else
    wait until ACK for previously sent data and accumulate data in send buffer (data)
    And after receiving the ACK send(data)

Dies hilft bei Anwendungen wie Telnet. Das Warten auf die ACK kann jedoch die Latenz beim Senden von Streaming-Daten erhöhen. Wenn der Empfänger die "verzögerte ACK-Richtlinie" implementiert, führt dies außerdem zu einer vorübergehenden Deadlock-Situation. In solchen Fällen ist es besser, den Nagle-Algorithmus zu deaktivieren.

Daher wird TCP_NODELAY zum Deaktivieren des Nagle-Algorithmus verwendet.

TCP_CORK sammelt aggressiv Daten. Wenn TCP_CORK in einem Socket aktiviert ist, werden keine Daten gesendet, bis der Puffer ein festes Limit erreicht. Ähnlich wie Nagles Algorithmus werden auch Daten vom Benutzer akkumuliert, aber bis der Puffer eine feste Grenze erreicht hat, werden erst ACK empfangen. Dies ist nützlich, wenn Sie mehrere Datenblöcke senden. Bei der Verwendung von TCP_CORK müssen Sie jedoch vorsichtiger vorgehen.

Bis zum 2.6er Kernel schließen sich beide Optionen gegenseitig aus. Im späteren Kernel können beide zusammen existieren. In diesem Fall wird TCP_CORK stärker bevorzugt.

Ref:

70
theB

TCP_NODELAY

Wird verwendet, um den Nagle-Algorithmus zu deaktivieren, um TCP/IP-Netzwerke zu verbessern und die Anzahl der Pakete zu verringern, indem gewartet wird, bis eine Bestätigung der zuvor gesendeten Daten empfangen wird, um die akkumulierten Pakete zu senden.

// Aus dem tcp (7) Handbuch:

TCP_CORK (oder TCP_NOPUSH in FreeBSD)

Wenn gesetzt, senden Sie keine Teilbilder aus. Alle in der Warteschlange befindlichen Teilrahmen werden gesendet, wenn die Option erneut deaktiviert wird. Dies ist nützlich, wenn Sie den Kopfzeilen vor dem Aufruf von sendfile(2) voranstellen oder den Durchsatz optimieren möchten. Wie derzeit implementiert, gibt es eine ** 200-Millisekunden-Obergrenze ** für die Zeit, für die die Ausgabe durch TCP_CORK Verkorkt wird. Wenn diese Obergrenze erreicht ist, werden in der Warteschlange befindliche Daten automatisch übertragen. Diese Option kann erst seit Linux 2.5.71 mit TCP_NODELAY Kombiniert werden. Diese Option sollte nicht in Code verwendet werden, der portabel sein soll.

21
Hussein Galal

Es ist eine Optimierung, so wie jede Optimierung:

  1. Benutze es nicht
  2. Warten Sie, bis die Leistung zu einem Problem wird, und stellen Sie dann fest, dass die Socket-Latenz definitiv die Ursache dafür ist. Tests haben gezeigt, dass dies definitiv Abhilfe schafft.

Grundsätzlich soll vermieden werden, dass mit sendfile () und seinen Freunden mehrere Frames gesendet werden müssen, in denen ein einzelner Frame verwendet werden kann.

Wenn Sie beispielsweise auf einem Webserver die Header gefolgt vom Dateiinhalt senden, werden die Header im Arbeitsspeicher zusammengestellt und die Datei wird dann direkt vom Kernel gesendet. Mit TCP_CORK können Sie die Header und den Anfang der Datei in einem einzigen Frame senden lassen, auch mit TCP_NODELAY, wodurch der erste Block ansonsten sofort gesendet würde.

7
MarkR

TCP_CORK ist das Gegenteil von TCP_NODELAY. Ersteres erzwingt eine Paketakkumulationsverzögerung; Letzteres deaktiviert es.

0
fche