1 Punkte von GN⁺ 2024-06-25 | 1 Kommentare | Auf WhatsApp teilen
  • Bei Live-Video und Gesprächen im Internet geht es nicht primär um „unzuverlässige Übertragung“, sondern darum, veraltete Daten zu verdrängen und die neuesten Daten rechtzeitig zu übertragen
  • Wenn Router überlastete Pakete nicht verwerfen, sondern lange in Warteschlangen halten, entsteht Bufferbloat, was bei Echtzeitdiensten zu Verzögerungen führen kann, die schlimmer sind als Buffering
  • Wer ein Protokoll direkt über UDP baut, muss Neuübertragungen, Congestion Control, Verschlüsselung, RTT-Schätzung, Pfadvalidierung, Flow Control usw. erneut implementieren; daher ist die Nutzung einer QUIC-Bibliothek sicherer
  • Schon mit QUIC allein lässt sich durch die Kombination aus latenzbasierter Congestion Control, unabhängiger Stream-Aufteilung und Priorisierung Rechtzeitigkeit ohne Datagramme erreichen
  • QUIC-, WebTransport- und MoQ-Standards unterstützen zwar Datagramme, doch statt ein neues Videoprotokoll erneut über UDP zu stapeln, ist es besser, sich am Media over QUIC-Ansatz zu orientieren

Das Ziel ist nicht „Unzuverlässigkeit“, sondern Rechtzeitigkeit

  • Die Wahl zwischen TCP und UDP wird oft als Gegensatz zwischen „zuverlässiger Übertragung“ und „unzuverlässiger Übertragung“ erklärt, aber Anwendungen wollen nicht Unzuverlässigkeit an sich
  • Bei Live-Video oder Gesprächen im Internet ist es wichtiger, dass die neuesten Daten zuerst ankommen, als dass alle alten Daten vollständig eintreffen
  • In Echtzeitgesprächen will man weder einen Buffering-Spinner über Gesichtern sehen noch Audio von vor 5 Sekunden hören
  • Die Live-Video-Branche und die Spieleindustrie nutzen für diese Art von Rechtzeitigkeit oft UDP-Datagramme statt TCP-Streams

Datagramme und Netzwerk-Warteschlangen

  • Ein Datagramm ist ein Umschlag aus Nullen und Einsen, der von einer Quelladresse zu einer Zieladresse gesendet wird; als sichere Größe gelten im Allgemeinen 1200 Byte
  • Datagramme können stillschweigend verloren gehen und auch in anderer Reihenfolge ankommen
  • Auf der physischen Schicht werden Daten in analoge Signale umgewandelt und über das Medium übertragen; dabei können Serialisierung, Deserialisierung, Buffering, Queueing, Neuübertragung, Verwerfen, Beschädigung, Verzögerung, Neuordnung, Duplikation und Verlust auftreten
  • Wenn zu viele Daten ins Netzwerk eingespeist werden, verwerfen Router Daten nicht an beliebigen Bitpositionen, sondern an Paketgrenzen

Bufferbloat und Congestion Control

  • Wenn Router Pakete nicht sofort verwerfen, sondern in Warteschlangen aufstauen, entsteht Bufferbloat
  • Bufferbloat kann alle Pakete um mehrere Sekunden verzögern und ist damit der Worst Case für Echtzeitübertragung
  • Um Queueing zu vermeiden, muss man anhand des Feedbacks zu Paketankunftszeiten das Queueing im Router abschätzen, damit der Sender seine Sendemenge reduziert und die Queue leert
  • Dieser Bereich gehört zur Congestion Control; Pakete mit unbegrenzter Rate zu senden, kann in einer Katastrophe enden

Was man sich aufhalst, wenn man direkt auf UDP aufbaut

Rechtzeitigkeit mit QUIC-Streams herstellen

  • Es gibt drei zentrale Wege, in QUIC Rechtzeitigkeit zu erreichen
    • Buffer-Aufblähung vermeiden: Latenzbasierte Congestion Control wie BBR erkennt Queueing und reduziert die Sendemenge
    • Das transport-wide-cc von WebRTC kann als Beispiel für einen besseren Ansatz gelten
    • Stream-Aufteilung: Innerhalb jedes Streams sind Bytes geordnet und werden zuverlässig übertragen; Streams können atomare Einheiten wie Videoframes, Spiel-Updates, Chat-Nachrichten oder JSON-Blobs sein
    • Stream-Priorisierung: Streams sind unabhängig und können unabhängig von ihrer Reihenfolge ankommen; dem QUIC-Stack kann mitgeteilt werden, wichtige Streams zuerst auszuliefern
    • Streams mit niedriger Priorität können verhungern und lassen sich schließen, um Bandbreitenverschwendung zu vermeiden
  • Dieser Ansatz ist der Kern von Media over QUIC
  • Der Fire-and-Forget-Charakter von Datagrammen passt nur dann, wenn echte Echtzeitlatenz erforderlich ist; sonst können QUIC-Streams verwendet werden

Kompromisse und Ausnahmen rund um Datagramme

  • QUIC und verwandte Standards enthalten auch Datagramm-Unterstützung
  • Datagramm-Unterstützung kann aufgenommen werden, weil die Implementierung trivial ist und Experimente erlaubt
  • OPUS hat eingebaute FEC-Unterstützung; damit ist es ein Beispiel dafür, dass MoQ das Senden jedes Audio-„frame“ als Datagramm unterstützen kann
  • Das ältere Protokoll DNS kann als Ausnahme gelten, aber für neue Designs sei eine Richtung wie DNS over HTTPS vorzuziehen
  • Das Fazit lautet: Statt ein neues Videoprotokoll erneut über UDP zu bauen, sollte man sich an Media over QUIC beteiligen

1 Kommentare

 
GN⁺ 2024-06-25
Meinungen auf Hacker News
  • Die Probleme von TCP treten zwar häufig in Bereichen mit hoher Bandbreite und niedriger Latenztoleranz wie HFT oder Video auf, aber auch in Netzen mit geringer Bandbreite und hoher Latenz ist TCP nicht besonders gut
    In einer Umgebung wie NB-IoT etwa, in der die Round-Trip-Latenz im schlimmsten Fall 10 Sekunden beträgt, wird Round-Trip-Zeit für Handshake und MTU-Erkennung verschwendet; es wird weiter versucht, Daten zu übertragen, die nicht mehr nützlich sind; und wenn schlechtere Abdeckung die Latenz erhöht, interpretiert TCP das als paketverlustbedingte Überlastung und reduziert die Bandbreite
    Außerdem können Load Balancer oder Middleboxes die Verbindung kappen nach dem Motto „seit 4 Sekunden keine Antwort, also ist sie wohl weg“, und weil TCP Pakete ohne Rücksicht auf die Datenstruktur aufteilt, ist es ebenfalls unschön, dass man sie erst interpretieren kann, wenn alles empfangen wurde
    • TCP geht davon aus, dass alle Daten als linearer Stream der Reihe nach ankommen, und wenn das n-te Paket nicht empfangen wurde, zeigt es auch das (n+1)-te Paket der Anwendung nicht an
      In manchen Fällen ist das nützlich, aber oft kann man das (n+1)-te Paket verwenden, auch wenn das n-te noch fehlt
      Bei großen Dateiübertragungen kann man mit Erasure Coding 5 % Paketverlust automatisch behandeln oder Fountain Codes verwenden und so lange senden, bis der Empfänger sagt: „Ich habe alles“
      Fountain Codes sind die Methode, mit der Weltraumsonden im tiefen All Daten senden, und die Latenz bis Jupiter oder Mars ist ziemlich erheblich
    • Das gilt besonders bei TLS, und heutzutage ist TLS bei den wichtigsten Anwendungsfällen praktisch der Standard
      Erst wenn der TCP-Handshake abgeschlossen ist, kann der TLS-Handshake beginnen; QUIC bietet dagegen Unterstützung auf Protokollebene, um die TLS-Aushandlung im initialen Handshake abzuwickeln
      Es wirkt zwar eleganter, Netzwerkprotokoll und Verschlüsselung lose kombinieren zu können, aber in einer Welt, in der inzwischen fast jede Übertragung verschlüsselt ist, scheint der praktische Vorteil größer zu sein, pro Verbindung eine Round-Trip-Zeit einzusparen
    • Ich frage mich, ob heutzutage nicht auch die Wi-Fi-Schicht unter TCP häufig eigene Retransmits für Verluste durch schwache oder verrauschte Signale macht
    • Ich frage mich, ob NB-IoT heutzutage tatsächlich genutzt wird. Ich erinnere mich, dass es einmal enorm gehypt wurde, aber danach scheint das Thema verschwunden zu sein
  • Für Streaming hochfrequenter Sensordaten verwendet man einfach UDP-Datagramme
    Im R&D-Bereich wurde ein neues System mit QUIC gebaut, das die meisten Probleme mit außer der Reihenfolge ankommenden Daten gelöst hat, aber Drittanbieter-Sensoren, die ohne Adapter direkt unterstützt werden müssen, können nur UDP; daher werden weiterhin für alles UDP-Datagramme verwendet
    • Auch fast alle Media-Art-Systeme weltweit nutzen OSC über UDP
    • Mir kamen hochfrequente Sensordaten in den Sinn; ich frage mich, ob es Zahlen zur Stromeinsparung gegenüber TCP gibt
    • Ich frage mich, in welcher Sprache dieses System gebaut wurde. Ziemlich cool
    • Um Zuverlässigkeit über UDP zu bekommen, hätte man auch RoCE verwenden können
  • Es mag wie Haarspalterei wirken, aber ich halte es für problematisch, UDP als unreliable zu bezeichnen
    Der gebräuchlichere und bessere Ausdruck ist best-effort: UDP versucht die Zustellung von Datagrammen nach bestem Vermögen, nur können Datagramme eben verworfen werden
    Das bedeutet nicht, dass UDP grundsätzlich nicht vertrauenswürdig wäre
    https://en.wikipedia.org/wiki/Best-effort_delivery
    • best-effort ist für Menschen außerhalb dieses Bereichs ein beschönigender und verwirrender Ausdruck, und für englische Muttersprachler kann das sogar noch stärker gelten
      Tatsächlich bedeutet es nicht, dass man bis zum Ende alles versucht, um eine Nachricht von A nach B zu schicken, sondern eher „wir haben es versucht“
      Wenn ein Router auf dem Pfad überlastet ist oder durch ein Link-Flap vor dem schnellen Rerouting etwa 50 ms lang ein Blackhole entsteht, heißt es gewissermaßen: „Na ja, versucht haben wir es“
      TCPs zuverlässige Zustellung dagegen versucht es mehrfach erneut und liefert der Anwendung einen korrekt geordneten Datenstream
      reliable/unreliable mögen ebenfalls schlechte Begriffe sein, aber es ist schwer zu behaupten, best-effort sei besser
      Nicht zuverlässige Systeme sind zu etwa 95 % großartig und auch gut für den rohen Durchsatz, aber die letzten 5 % machen oft einen sehr großen Unterschied
    • In der Netzwerktechnik ist best effort delivery ein ausweichender Begriff, der nicht besser ist als unreliable, und man könnte ihn im Grunde abschaffen
      „Anstrengung“ bedeutet gewöhnlich ein gewisses Maß an Beharrlichkeit angesichts von Schwierigkeiten; ein Paket zu verwerfen, weil Ressourcen knapp werden, ist schwerlich Anstrengung zu nennen, geschweige denn best effort
      „Best efforts“ als Rechts- und Geschäftssprache ist zwar schwächer als eine feste Zusage, bedeutet aber nicht, offen die Hände in den Schoß zu legen; die Verwendung in der Netzwerktechnik ist davon ziemlich verschieden
      Unabhängig davon gewährleisten auch die Checksummen von UDP und TCP die Integrität nicht besonders gut, wenn ein Datagramm zugestellt wurde; sie sind nur etwas besser als Hardware
    • Ich dachte, „Datagramme können verworfen werden“ sei genau die Bedeutung von unreliable; ich bin mir nicht sicher, welches Missverständnis man vermeiden will
    • Eine Transportschicht als unreliable zu bezeichnen, ist keine gute Formulierung. Zuverlässigkeit ist eine Eigenschaft eines Systems, nicht einer Transportmethode; man kann mit TCP unzuverlässige Systeme bauen und mit UDP zuverlässige Systeme
      Allerdings erweckt best-effort den Eindruck, als würde etwas unternommen, um die Zustellung zu garantieren; tatsächlich werden Pakete, die merkwürdig aussehen oder Pech haben und auf einen vollen Buffer treffen, einfach verworfen
      lossy gefällt mir, aber das gehört zu diesem Namensgebungsproblem aus „es gibt nur zwei schwierige Dinge“
    • Seit den 80ern nennt man es unreliable transport, und tatsächlich stimmt das auch
      Wenn Pakete ankommen müssen, nimmt man TCP; wenn es nicht groß darauf ankommt, nimmt man UDP
      Das ist zwar eine vereinfachte Erklärung, aber best effort ist ein dummer Begriff, und darin steckt keine Anstrengung
  • Ich finde, die Stream-Abstraktion macht es viel zu leicht, fragile Programme zu schreiben, die sich nach einem Verbindungsabbruch nur langsam oder gar nicht erholen, und sie legt der Transportschicht auch zu viele Beschränkungen auf
    Congestion Control ist sicher notwendig, aber darüber hinaus habe ich viele Zweifel
    In einer Datagramm-zuerst-Welt hätte man mehrere Datenlinks sehr effizient bündeln oder problemlos über Netzwerkgrenzen hinweg roamen können, ohne die Verbindung zu unterbrechen
    Viele Anwendungen können Frames, die außer der Reihenfolge ankommen, ohne zusätzliche Kosten verarbeiten und könnten deutlich schneller sein, wenn sie passend zum UDP-Modell geschrieben würden
    • Die Behauptung lautet, TCP sei so bequem, dass Software nicht ordentlich geschrieben werde; zugleich soll man glauben, dass in einer viel komplexeren Datagramm-zuerst-Welt perfekt robuste und effiziente Software entstehen würde – das ist wenig überzeugend
      Tatsächlich wird Software nicht automatisch zuverlässiger oder effizienter, nur weil man zu einer weniger zuverlässigen Transportmethode wechselt

Vielmehr nehmen die Fehlermodi und die Komplexität, mit denen das Team umgehen muss, erheblich zu

  • Bei Anwendungen mit geeigneten Fehlerkorrekturcodes könnte auch Congestion Control optional sein
    Wenn es irgendwo in der Verbindung jedoch einen engen Flaschenhals gibt, scheint es wenig sinnvoll, massenhaft Pakete zu erzeugen, die an diesem Engpass ohnehin verworfen werden
  • Ich frage mich, an welche Art von Anwendungen gedacht ist. Welche Systeme, die heute typischerweise mit TCP geschrieben werden, ließen sich auf UDP umstellen?
    Websites, Audio und Video kommen im Allgemeinen nicht gut mit Frames zurecht, die in falscher Reihenfolge ankommen, und die meisten wollen nicht, dass Audio oder Video aussetzt
    Einige Videospiele können fehlende Pakete ignorieren, aber solche Fälle sind bereits mit UDP geschrieben
  • Ein Punkt, der selten erwähnt wird: Bei Congestion verwerfen viele Netzwerke UDP-Pakete zuerst
    Der Gedanke dahinter ist, dass diese Pakete nicht erneut übertragen werden und das daher eine wirksame Methode ist, überschüssigen Traffic zu reduzieren
    Inzwischen gibt es Protokolle über UDP, die aggressiv erneut übertragen; ich frage mich, wie das die Lage verändert hat
    Ich erinnere mich auch, dass QUIC vor einigen Jahren deswegen im Vergleich zu HTTP/1 und HTTP/2 Probleme mit Retransmissions hatte
  • Ich habe versucht, den Clickbait-Titel mit Formulierungen aus dem Artikel selbst zu ändern
    Wenn sich im Artikel eine repräsentativere Formulierung findet, kann er wieder geändert werden
    Das folgt der HN-Titelrichtlinie „Originaltitel verwenden, außer er ist irreführend oder Clickbait“: https://news.ycombinator.com/newsguidelines.html
  • Ich stimme der Prämisse dieses Beitrags nicht zu. UDP ist nicht um der Unzuverlässigkeit selbst willen da, sondern ein Kompromiss: Man erhält Geschwindigkeit und Effizienz und wählt dafür Best-Effort-Delivery statt Garantien
    Je nach Anwendung ist das sinnvoll
    Wenn in einem Echtzeit-Multiplayer-Spiel zum Beispiel die Verarbeitung hinterherhinkt, sind die verzögerten Einträge nicht mehr wichtig, weil sich der Spielzustand bereits geändert hat
    Auch bei High-Frequency-Trading-Anwendungen zählt in manchen Situationen nur die aktuellsten Marktdaten, nicht das, was vor 100 ms passiert ist
    • Das ist nicht die Prämisse des Artikels, sondern eine gängige Vorstellung, die der Autor anschließend korrigiert
      Der Artikel nennt auch Spiele und Live-Video als Beispiele, bei denen UDP passend ist
    • Wenn man weiterliest, sagt der Artikel im Grunde ebenfalls genau das
      Er ist so aufgebaut, dass zunächst eine „gängige Vorstellung“ vorgestellt und danach widerlegt wird
  • Dinge, die datagrammbasiert sein müssen, sind lokale Discovery, Broadcast und Paketkapselung
    Dazu gehören zum Beispiel lokale Discovery wie DHCP, SLAAC, UPnP, mDNS, tinc und BitTorrent, Broadcast wie Streaming im lokalen Netzwerk sowie Kapselung wie WireGuard, IPSec, OpenVPN und VLAN
    • Was in der Liste fehlt, sind Echtzeitmedien
      Schon Buffering für Neuordnung, ganz zu schweigen von Retransmissions, erhöht die Latenz; daher ist es besser, Verluste mit Fehlerkorrektur oder Packet Loss Concealment in Kauf zu nehmen
    • Aus der Perspektive von jemandem ohne viel Low-Level-Networking-Wissen: Ich frage mich, ob jemand erklären kann, warum diese Anwendungsfälle Datagramme brauchen
    • Spiele gehören ebenfalls dazu
  • Der Titel ist dummer Clickbait, und der Autor räumt das am Anfang auch ein
    UDP und TCP haben unterschiedliches Verhalten und unterschiedliche Trade-offs; man muss sie einfach verstehen, bevor man passend zum Anwendungsfall wählt
    Dieses Gatekeeping nach dem Muster „Tu niemals X“ ist nicht nötig
    • Wenn nicht in den 10 Minuten nach dem Kommentar ein Sternchen vor „never“ im Titel hinzugefügt wurde, ist dieses Sternchen eindeutig ein Hinweis darauf, dass es Detailbedingungen gibt
      Schon am Titel ist ziemlich klar, dass der Artikel kein Gatekeeping betreiben will, um UDP zu verbieten
      Tatsächlich schlägt der Autor am Ende des Artikels die Nutzung von QUIC vor, das auf UDP basiert
  • Die meisten Anwendungen und Fälle werden wohl sitzungsbasierte Verbindungen verwenden, aber es gibt auch Anwendungsfälle für direkte Datagramme, also kein Grund, davor Angst zu haben
    Natürlich muss man sich dann um deutlich mehr Details selbst kümmern
    Als Bonus ist es auch eine gute Möglichkeit, die Low-Level-Aspekte von Networking zu lernen
    • Die SteamNetworkingMessages API für Spieleentwicklung macht es möglich, diesen Ansatz in diesem Anwendungsfall gut zu nutzen, ohne sich um die Interna kümmern zu müssen