Ist es eine gute Idee, blockierende Streams in eine TCP-Verbindung zu multiplexen?

13

Ich brauche mehrere Duplexkanäle zwischen zwei Hosts. Es gibt eine Reihe von Vorteilen, nur eine TCP-Verbindung herzustellen. Aber ich bezweifle, dass Multiplexing einige unvermeidliche Probleme verursachen würde. Wird dies die Leistung beeinträchtigen oder die Latenz erheblich erhöhen? Und was ist mit der Speichernutzung und der CPU-Auslastung? Gibt es einen Vorschlag oder eine Einschränkung, die Sie geben möchten?

Sherwood Wang
quelle

Antworten:

10

TLDR: Der Hauptnachteil, den Sie beim Multiplexen mehrerer Kanäle über TCP bemerken können (wenn Sie es richtig machen), ist eine erhöhte Latenz wegen der Blockierung der Kopfzeile zwischen den Kanälen.

Fazit: Wenn dir die Latenz egal ist, solltest du in Ordnung sein.

Auf der anderen Seite bedeutet die Verwendung einer einzelnen TCP-Verbindung „weniger Wettbewerb mit anderen Flows und langlebigere Verbindungen, was wiederum zu einer besseren Auslastung der verfügbaren Netzwerkkapazität führt“ .

Head-of-Line-Blocking Blocking über TCP

Wenn Sie mehrere Kanäle über denselben TCP-Stream multiplexen, kann es zu einer Head-of-Line-Blockierung der Kanäle kommen :

Head-of-Line-Blocking (HOL) kann auftreten, wenn Transportprotokolle einen bestellten oder einen teilweise bestellten Dienst anbieten: Wenn Segmente verloren gehen, müssen nachfolgende Nachrichten auf die erfolgreiche Neuübertragung in der Empfängerwarteschlange warten und werden daher verzögert.

Wenn Sie mehrere Streams auf TCP multiplexen, erhalten Sie HOL zwischen den Kanälen .

Wenn Kanal A den TCP-Sendepuffer gefüllt hat, müssen Sie warten, bis alle diese Daten empfangen wurden, bevor neue Daten von Kanal B effektiv an die Remote-Anwendungsschicht übertragen werden können.

Weitere Informationen zum Multiplexen von Kanälen über TCP und zur Diskussion von Hackernews finden Sie unter "Multiplexen über TCP" .

Beispiele für das Multiplexen über TCP

Kanalmultiplex über SSH (über TCP)

Ein typisches Beispiel hierfür ist SSH. SSH können mehrere Kanäle (siehe multiplexen ControlMaster, ControlPathund ControlPersistin OpenSSH). Dadurch werden die Kosten für die Initialisierung einer neuen SSH-Sitzung reduziert (anfängliche Latenz), aber eine starke Übertragung auf einem Kanal erhöht normalerweise die Latenz / Interaktivität der anderen (was nicht der Fall ist, wenn Sie mehrere TCP-Streams verwenden): Wenn Sie eine interaktive Sitzung verwenden Wenn Sie eine umfangreiche Dateiübertragung über denselben Kanal starten, wird Ihre Sitzung wesentlich weniger interaktiv.

Multiplexed HTTP / 2 über TCP

HTTP / 2 verwendet das Multiplexen von Anforderungen / Antworten über TCP, um die HOL-Blockierung zu beheben. Diese Funktion wird in vielen Artikeln und Artikeln über HTTP / 2 beworben. Der HTTP / 2-RFC behauptet:

HTTP / 1.1 fügte Anforderungs-Pipelining hinzu, das jedoch nur teilweise die Parallelität von Anforderungen ansprach und weiterhin unter Head-of-Line-Blockierung leidet.

[...]

Das resultierende Protokoll ist netzwerkfreundlicher, da im Vergleich zu HTTP / 1.x weniger TCP-Verbindungen verwendet werden können. Dies bedeutet weniger Wettbewerb mit anderen Verkehrsströmen und längerfristige Verbindungen, was wiederum zu einer besseren Auslastung der verfügbaren Netzwerkkapazität führt.

Was jedoch nicht besprochen wird, ist, dass die HOL-Blockierung nicht vollständig gelöst ist. HTTP / 2 über TCP noch leidet ) von TCP-Ebene HOL - Blocking .

Dies wird in diesem LWN-Artikel über QUIC erörtert :

HTTP / 2 wurde entwickelt, um dieses Problem mithilfe mehrerer "Streams" zu beheben, die in eine einzelne Verbindung integriert sind . [...] es entsteht ein neues Problem: Der Verlust eines einzelnen Pakets verzögert die Übertragung aller Streams auf einmal und führt zu neuen Latenzproblemen. Diese Variante des Head-of-Line-Blocking-Problems ist in TCP selbst integriert und kann nicht mit weiteren Optimierungen auf HTTP-Ebene behoben werden.

Andere Multiplexstrategien

SCTP

Dies ist eines der Unterscheidungsmerkmale von SCTP (Multistreaming). Sie können mehrere unabhängige Streams in derselben SCTP-Zuordnung haben und jeder Stream blockiert nicht die anderen.

Weitere Informationen zur Verwendung von SCTP finden Sie unter SSH über SCTP - Optimieren eines Mehrkanalprotokolls durch Anpassung an SCTP , um eine kanalübergreifende HOL-Blockierung in SSH zu vermeiden:

SCTP behält nur die Reihenfolge der Nachrichten innerhalb eines einzelnen Streams bei, um einen Effekt, der als Head-of-Line-Blocking bezeichnet wird, abzuschwächen. Wenn eine Nachricht verloren geht, müssen die nachfolgenden Nachrichten verzögert werden, bis die verlorene erneut übertragen wird, um die Bestellung zu erhalten. Da nur Nachrichten desselben Streams verzögert werden müssen, verringert sich die Anzahl der betroffenen Nachrichten nach einem Verlust.

[...]

Durch die Zuordnung der SSH-Kanäle zu den SCTP-Streams wird SSH der Vorteil des Multi-Streaming zur Verfügung gestellt, wodurch das Blockieren von Head-of-Line- Kanälen verringert wird .

Die Bereitstellung von SCTP ist nicht unbedingt einfach (aufgrund der Verfügbarkeit des Betriebssystems, der Interaktion mit der Middlebox usw.). Eine Möglichkeit ist, es über UDP im Userspace zu implementieren .

QUIC (Multiplexing über UDP)

Ein weiteres Beispiel ist das experimentelle QUIC- Protokoll, das zum Multiplexen von HTTP über UDP verwendet wird (da das Multiplexen mehrerer Streams über TCP als HTTP / 2 unter HOL-Blockierung leidet ):

QUIC ist ein neuer Transport, der die Latenz im Vergleich zu TCP reduziert . An der Oberfläche ist QUIC TCP + TLS + HTTP / 2 sehr ähnlich, das auf UDP implementiert ist.

[...]

Multiplexing ohne Head-of-Line-Blocking

Googles QUIC-Protokoll: Das Verschieben des Webs von TCP nach UDP bietet einen guten Überblick über das Blockieren von QUIC und HOL, wenn Kanäle über TCP gemultiplext werden.

In einer kürzlich erschienenen Präsentation wurde behauptet, dass HTTP über QUIC die Latenz verbessert, die Verbesserung der HOL-Blockierung jedoch einen „geringeren Vorteil“ darstellt:

0-RTT, über 50% der Latenzverbesserung

[…]

Weniger auf Timeout basierende Neuübertragungen verbessern die Latenz des Tails […]

Andere, kleinere Vorteile, z. B. Head of Line Blocking

Beachten Sie, dass QUIC als "sehr ähnlich zu TCP + TLS + HTTP / 2, das auf UDP implementiert ist" beschrieben wird, in der Tat ein Allzwecktransport ist, der unabhängig von HTTP / 2 verwendet werden kann und möglicherweise Ihren Anforderungen entspricht.

Hinweis: HTTP / QUIC wird als HTTP / 3 standardisiert .

ysdx
quelle
Ich denke nicht, dass HOL ein echtes Problem ist, wenn es einen Flusskontrollmechanismus gibt. Wenn Sie mehrere TCP-Verbindungen öffnen, werden auch mehrere Fensterpuffer erstellt, die möglicherweise nicht speichereffizienter sind.
Sherwood Wang
Ich habe über SCTP nachgedacht. Aber es scheint, dass SCTP noch nicht sehr portabel war und NAT-Geräte schlecht damit umgehen.
Sherwood Wang
@SherwoodWang, Ein Kontrollflussmechanismus in Ihrem Multiplexing-Protokoll verhindert nicht, dass HOL blockiert wird.
ysdx
Wenn beim Sender keine Daten verfügbar sind, sendet der Sender möglicherweise einen Flusssteuerungsrahmen, um den Empfänger anzuweisen, auf den nächsten gemultiplexten Kanal umzuschalten und weiterhin Datenrahmen dieses Kanals zu senden. Wenn der Empfänger voll ist, kann auch ein ähnlicher Mechanismus verwendet werden. Es verhindert definitiv das Blockieren von HOL mit nur einer halben Roundtrip-Latenz.
Sherwood Wang
@SherwoodWang, das TCP-HOL-Problem ist wirklich auf der Empfängerseite. Wenn bei der Übertragung ein Paket verloren gegangen ist, kann der Empfänger dem Benutzerbereich die folgenden Pakete nicht übergeben. Es muss warten, bis das Paket erneut gesendet und empfangen wurde. Alle verbleibenden Daten (Ereignis von einem anderen gemultiplexten Datenstrom) werden blockiert, bis dieses Paket empfangen wird.
ysdx
3

Ich würde sagen, dass Sie den ZeroMQ-Leitfaden lesen müssen. Die darin enthaltenen Muster mit den Gründen und Nachteilen sind eine wichtige Lektüre.

Ansonsten ist es kein Problem, den Netzwerkkanal von Ihrer Anwendungsdatenlieferung zu trennen. Sie müssen das Muxen und Demuxen der gesendeten Datenpakete übernehmen (und ich würde hier eine paketbasierte Architektur empfehlen, bei der keine Daten in einem kontinuierlichen Fluss gestreamt werden) und das Puffern der Daten an jedem Ende.

Andernfalls sollte die Auswirkung gering sein. Möglicherweise benötigen Sie mehr - aber nur geringfügig - Speicher, um Daten zu puffern, und ein wenig mehr CPU, da Sie mehr Code zum Sperren und Parsen von Paketen verarbeiten, aber nichts Bedeutendes. (es sei denn, Sie schreiben einen Spezialisten, der einen hohen Durchsatz und eine hohe Leistung erfordert.)

gbjbaanb
quelle
2

Ja, genau nach diesem Prinzip habe ich ein Client-Server-Datenbanksystem aufgebaut.

Die auf die eine TCP-Verbindung gemultiplexten Kanäle senden jeweils Datenpakete, die dann auf die jeweiligen Empfänger am anderen Ende aufgeteilt werden.

Das Überbrücken der Verbindung um einen einzigen Kanal erfolgt durch den TCP-Verbindungssender, der im Round-Robin-Verfahren auswählt, welches Paket von den Kanälen gesendet werden soll, auf denen Daten zum Senden bereitstehen.

Um den Fall zu bewältigen, dass ein Kanal beschließt, ein 1-GB-Paket zu senden und alle anderen auszusperren, kann der Absender ein Paket in Blöcke aufteilen und nur einen Block senden, bevor ein anderer Kanal an die Reihe kommt. Am empfangenden Ende wird der Zusammenbau von Stücken zu einem Paket durchgeführt, bevor der Empfänger das Paket sieht.

Martin Kochanski
quelle