Es ist eine Optimierung, also wie jede Optimierung:
- Verwenden Sie es nicht
- Warten Sie, bis die Leistung zu einem Problem wird, und nachdem Sie festgestellt haben, dass die Socket-Latenz definitiv die Ursache dafür ist, und Tests beweisen, dass dies definitiv behoben wird, UND dies der einfachste Weg ist, es zu beheben, tun Sie es.
Grundsätzlich soll vermieden werden, dass mehrere Frames gesendet werden müssen, wo ein einzelner Frame mit sendfile() und seinen Freunden verwendet werden kann.
So senden Sie beispielsweise in einem Webserver die Header gefolgt vom Dateiinhalt, die Header werden im Speicher zusammengestellt, die Datei wird dann direkt vom Kernel gesendet. TCP_CORK ermöglicht es Ihnen, die Header und den Anfang der Datei in einem einzigen Frame zu senden, sogar mit TCP_NODELAY, was sonst dazu führen würde, dass der erste Chunk sofort gesendet wird.
TCP_NODELAY
Wird verwendet, um den Algorithmus von Nagle 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 gesammelten Pakete zu senden.
//Aus dem TCP(7)-Handbuch:
TCP_CORK
(oder TCP_NOPUSH
in FreeBSD)
Wenn gesetzt, keine Teilbilder aussenden. Alle anstehenden Teilrahmen werden gesendet, wenn die Option wieder gelöscht wird. Dies ist nützlich, um Header voranzustellen, bevor sendfile(2)
aufgerufen wird , oder zur Durchsatzoptimierung. Wie derzeit implementiert, gibt es eine Obergrenze von 200 Millisekunden auf die Zeit, für die die Ausgabe von TCP_CORK
verkorkt wird . Wenn diese Obergrenze erreicht ist, werden die in der Warteschlange befindlichen Daten automatisch übertragen . Diese Option kann mit TCP_NODELAY
kombiniert werden erst seit Linux 2.5.71. Diese Option sollte nicht in Code verwendet werden, der portierbar sein soll.
Zunächst einmal deaktivieren nicht beide den Nagle-Algorithmus.
Der Algorithmus von Nagle dient zum Reduzieren einer größeren Anzahl kleiner Netzwerkpakete in der Leitung. 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. Senden Sie dann 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 außerdem die „verzögerte ACK-Richtlinie“ implementiert, wird dies eine vorübergehende Deadlock-Situation verursachen. In solchen Fällen ist es besser, den Nagle-Algorithmus zu deaktivieren.
TCP_NODELAY wird also zum Deaktivieren des Nagle-Algorithmus verwendet.
TCP_CORK sammelt aggressiv Daten. Wenn TCP_CORK in einem Socket aktiviert ist, sendet es keine Daten, bis der Puffer bis zu einer festen Grenze gefüllt ist. Ähnlich wie der Algorithmus von Nagle sammelt er auch Daten vom Benutzer, aber bis der Puffer bis zu einer festen Grenze gefüllt ist, nicht bis zum Empfang von ACK. Dies ist nützlich, wenn mehrere Datenblöcke gesendet werden. Bei der Verwendung von TCP_CORK müssen Sie jedoch vorsichtiger sein.
Bis Kernel 2.6 schließen sich diese beiden Optionen gegenseitig aus. Aber im späteren Kernel können beide zusammen existieren. In diesem Fall wird TCP_CORK bevorzugt.
Ref:
- http://baus.net/on-tcp_cork/
- http://ccr.sigcomm.org/archive/2001/jan01/ccr-200101-mogul.pdf