1 puntos por GN⁺ 2024-06-25 | 1 comentarios | Compartir por WhatsApp
  • En video en vivo y conversaciones por internet, lo importante no es la “entrega no confiable” en sí, sino descartar los datos viejos y entregar los más recientes a tiempo
  • Si un router no descarta los paquetes congestionados y en cambio los acumula mucho tiempo en cola, aparece el bufferbloat, que en servicios en tiempo real puede causar una latencia peor que el buffering
  • Si se construye un protocolo directamente sobre UDP, hay que volver a implementar retransmisión, control de congestión, cifrado, estimación de RTT, validación de ruta y control de flujo, entre otras cosas, así que es más seguro usar una biblioteca de QUIC
  • Solo con QUIC ya se puede lograr oportunidad sin datagramas combinando control de congestión basado en latencia, separación independiente de streams y priorización
  • Los estándares de QUIC, WebTransport y MoQ incluyen soporte para datagramas, pero la conclusión es que conviene más ajustarse al flujo de Media over QUIC que volver a montar un nuevo protocolo de video sobre UDP

La meta no es la “inestabilidad”, sino la oportunidad

  • La elección entre TCP y UDP suele explicarse como “entrega confiable” frente a “entrega no confiable”, pero eso no significa que la aplicación quiera inestabilidad como tal
  • En video en vivo o conversaciones por internet, suele ser más importante que llegue antes el dato más reciente que recibir todos los datos viejos
  • En una conversación en tiempo real hay que evitar situaciones como ver un spinner de buffering sobre la cara de alguien o escuchar una voz de hace 5 segundos
  • La industria del video en vivo y la del gaming suelen usar datagramas UDP en lugar de streams TCP para lograr esa oportunidad

Datagramas y colas de red

  • Un datagrama es un sobre de 0 y 1 que va de una dirección de origen a una de destino, y por lo general se considera que 1200 bytes es un tamaño seguro
  • Un datagrama puede perderse silenciosamente y también puede llegar fuera de orden
  • En la capa física, los datos se convierten en señales analógicas para atravesar el medio, y pueden ocurrir serialización, deserialización, buffering, encolado, retransmisión, descarte, corrupción, demora, reordenamiento, duplicación y pérdida
  • Cuando entra demasiada información a la red, los routers no descartan bits arbitrarios, sino datos en los límites de los paquetes

Bufferbloat y control de congestión

  • Si el router no descarta los paquetes de inmediato y en cambio los acumula en cola, aparece el bufferbloat
  • El bufferbloat puede retrasar todos los paquetes durante varios segundos, creando el peor escenario posible para la entrega en tiempo real
  • Para evitar el encolado, hay que estimar la cola del router a partir de la retroalimentación del tiempo de llegada de los paquetes, y el emisor debe reducir su tasa de envío para vaciarla
  • Esta área corresponde al control de congestión, y enviar paquetes a velocidad ilimitada puede terminar en un desastre

Lo que hay que asumir si se construye directo sobre UDP

Cómo lograr oportunidad con streams de QUIC

  • La forma de alcanzar oportunidad en QUIC puede resumirse en tres puntos
    • Evitar la inflación del buffer: un control de congestión basado en latencia como BBR detecta el encolado y reduce la tasa de envío
    • El transport-wide-cc de WebRTC puede verse como un ejemplo de una mejor aproximación
    • Separación de streams: los bytes dentro de cada stream mantienen orden y se entregan de forma confiable, y cada stream puede representar una unidad atómica como un frame de video, una actualización de juego, un mensaje de chat o un blob JSON
    • Priorización de streams: como los streams son independientes, pueden llegar sin relación de orden entre sí, y se puede indicar al stack de QUIC que entregue antes los streams importantes
    • Los streams de baja prioridad pueden quedar hambrientos, y para evitar desperdiciar ancho de banda se pueden cerrar
  • Este enfoque es el núcleo de Media over QUIC
  • La naturaleza fire-and-forget de los datagramas solo encaja cuando se necesita latencia en tiempo real; fuera de eso, se pueden usar streams de QUIC

Compromisos y excepciones alrededor de los datagramas

  • QUIC y los estándares relacionados también incluyen soporte para datagramas
  • El soporte para datagramas puede incluirse porque su implementación es trivial y permite experimentar
  • OPUS incorpora soporte de FEC, así que sirve como ejemplo de un caso en el que MoQ admite enviar cada “frame” de audio como datagrama
  • El protocolo antiguo DNS puede tratarse como una excepción, pero en diseños nuevos se considera preferible seguir una dirección como DNS over HTTPS
  • La conclusión es que, en vez de volver a construir un nuevo protocolo de video sobre UDP, es mejor sumarse a Media over QUIC

1 comentarios

 
GN⁺ 2024-06-25
Opiniones de Hacker News
  • Los problemas de TCP suelen aparecer en ámbitos con mucho ancho de banda y sensibles a la latencia, como HFT o video, pero TCP tampoco es especialmente bueno en redes de bajo ancho de banda y alta latencia
    Por ejemplo, en un entorno como NB-IoT, donde en el peor caso la latencia de ida y vuelta es de 10 segundos, se desperdicia tiempo de ida y vuelta en el handshake y el descubrimiento de MTU; además, intenta seguir transmitiendo datos que ya no sirven, y si la cobertura empeora y aumenta la latencia, TCP lo interpreta como pérdida de paquetes por congestión y reduce el ancho de banda
    También un load balancer o un middlebox puede cortar la conexión pensando “no hubo respuesta durante 4 segundos, así que habrá desaparecido”, y también es una pena que TCP divida los paquetes sin considerar la estructura de los datos, por lo que no se pueden interpretar hasta recibirlos completos
    • TCP asume que todos los datos llegan en orden como un stream lineal y, si no recibe el paquete n, tampoco muestra a la aplicación el paquete n+1
      En algunos casos eso es útil, pero muchas veces se puede aprovechar el n+1 aunque el n todavía no esté
      En transferencias de archivos grandes se podría manejar automáticamente una pérdida de paquetes del 5% con códigos de borrado, o usar fountain codes y seguir enviando hasta que el receptor diga “ya recibí todo”
      Los fountain codes son la forma en que las sondas del espacio profundo envían datos, y la latencia hasta Júpiter o Marte es bastante seria
    • Con TLS esto es especialmente cierto, y hoy TLS es prácticamente lo predeterminado en los principales casos de uso
      Hay que terminar el handshake de TCP para poder iniciar el handshake de TLS, pero QUIC tiene soporte a nivel de protocolo para manejar la negociación TLS dentro del handshake inicial
      Parecería más elegante poder combinar de forma laxa el protocolo de red y el cifrado, pero en un mundo donde casi todo el transporte ya va cifrado, la ventaja práctica de ahorrar un tiempo de ida y vuelta por conexión parece mayor
    • Me pregunto si hoy en día la capa Wi-Fi debajo de TCP no suele hacer sus propias retransmisiones por pérdidas causadas por señales débiles o con mucho ruido
    • Me pregunto si NB-IoT se usa realmente hoy en día. Recuerdo que en algún momento lo promocionaban muchísimo, pero después parece que dejó de ser tema
  • Para streaming de datos de sensores de alta frecuencia simplemente usamos datagramas UDP
    En R&D hicimos un sistema nuevo que usa QUIC y resolvió la mayor parte del problema de llegadas fuera de orden, pero como los sensores de terceros que tenemos que soportar directamente, sin adaptadores, solo pueden usar UDP, seguimos usando datagramas UDP para todo
    • Los sistemas de media art de todo el mundo también usan casi todos OSC sobre UDP
    • Me hizo pensar en datos de sensores de alta frecuencia; me pregunto si hay cifras de ahorro de energía frente a TCP
    • Me pregunto en qué lenguaje hicieron ese sistema. Suena bastante genial
    • Para obtener confiabilidad sobre UDP también podrían haber usado RoCE
  • Puede parecer una objeción menor, pero creo que hay un problema con llamar unreliable a UDP
    La expresión más común y mejor es best-effort: UDP hace el mejor intento por entregar datagramas, solo que los datagramas pueden descartarse
    Eso no significa que UDP sea inherentemente no confiable
    https://en.wikipedia.org/wiki/Best-effort_delivery
    • best-effort es una expresión eufemística y confusa para la gente de fuera del área, e incluso puede serlo más para hablantes nativos de inglés
      En realidad no significa que se hará todo lo posible para enviar un mensaje de A a B, sino algo más cercano a “se intentó”
      Si un router en la ruta está congestionado, o si por un flap de enlace se genera un agujero negro de unos 50 ms antes de una reruta rápida, termina siendo “bueno, lo intenté”
      En cambio, la entrega confiable de TCP reintenta varias veces y ofrece a la aplicación un stream de datos en orden
      reliable/unreliable también pueden ser malos términos, pero es difícil decir que best-effort sea mejor
      Los sistemas no confiables funcionan muy bien en un 95% y también son buenos para el throughput bruto, pero el último 5% muchas veces marca una diferencia enorme
    • En redes, best effort delivery no es más que un término evasivo que no mejora a unreliable, al punto de que se podría eliminar
      “Esfuerzo” normalmente implica cierta persistencia ante la dificultad, pero descartar paquetes porque hay problemas de recursos difícilmente puede llamarse esfuerzo, y mucho menos best effort
      En terminología legal y de negocios, “best efforts” es más débil que un compromiso definitivo, pero no significa lavarse las manos abiertamente; en redes, su uso es bastante distinto
      Por separado, los checksums de UDP y TCP tampoco garantizan muy bien la integridad cuando se entrega un datagrama; son apenas algo mejores que el hardware
    • Yo pensaba que “los datagramas pueden descartarse” era justamente lo que significa unreliable, así que no entiendo muy bien qué malentendido se intenta evitar
    • No es una buena expresión llamar unreliable a la capa de transporte. La confiabilidad es una propiedad del sistema, no del método de transporte; se puede construir un sistema no confiable con TCP y también uno confiable con UDP
      Dicho eso, best-effort da la impresión de que se hace algún esfuerzo para garantizar la entrega, cuando en realidad simplemente se descarta un paquete que parece raro o que tuvo la mala suerte de encontrarse con un buffer lleno
      Me gusta lossy, pero esto cae en el problema de nombres de “solo hay dos problemas difíciles”
    • Desde los 80 se le llama unreliable transport, y en realidad es correcto
      Si los paquetes tienen que llegar, usa TCP; si no importa demasiado, usa UDP
      Es una explicación simplificada, pero best effort es un término tonto, no hay ningún esfuerzo ahí
  • Creo que la abstracción de stream hace demasiado fácil crear programas frágiles que se recuperan lentamente cuando se corta la conexión, o que directamente no se recuperan, y también impone demasiadas restricciones a la capa de transporte
    El control de congestión claramente es necesario, pero fuera de eso tengo muchas dudas
    En un mundo priorizando los datagramas, no habría habido problemas para agrupar varios enlaces de datos de forma muy eficiente, o para hacer roaming cruzando fronteras de red sin cortar la conexión
    Muchas aplicaciones pueden manejar frames fuera de orden sin costo adicional, y si se escriben ajustándose al modelo UDP podrían ser mucho más rápidas
    • El argumento de que TCP es tan cómodo que el software no se escribe correctamente, pero que en un mundo priorizando los datagramas, mucho más complejo, deberíamos creer que saldría software perfectamente robusto y eficiente, no resulta muy convincente
      En la práctica, pasar a un transporte menos confiable no hace automáticamente que el software sea más confiable ni más eficiente

Más bien, aumentan mucho los modos de falla y la complejidad que el equipo tiene que manejar

  • En aplicaciones con códigos de corrección de errores adecuados, el control de congestión también podría ser opcional
    Pero si hay un cuello de botella estrecho en algún punto de la conexión, no parece tener mucho sentido generar una enorme cantidad de paquetes que de todos modos se van a descartar en ese cuello de botella
  • Me da curiosidad qué tipo de aplicaciones tienen en mente. ¿Qué sistemas que hoy se escriben comúnmente con TCP podrían cambiarse a UDP?
    Los sitios web, el audio y el video por lo general no encajan bien con frames fuera de orden, y la mayoría no quiere cortes en el audio o el video
    Algunos videojuegos pueden ignorar paquetes faltantes, pero esos casos ya están escritos con UDP
  • Un punto que no se menciona a menudo es que, cuando hay congestión, muchas redes descartan primero los paquetes UDP
    La idea es que, como esos paquetes no se van a retransmitir, es una forma efectiva de reducir el tráfico excedente
    Ahora hay protocolos sobre UDP que retransmiten de forma agresiva, y me pregunto cómo cambió eso la situación
    También recuerdo que hace unos años QUIC tuvo problemas de retransmisión frente a HTTP/1 y HTTP/2 por este motivo
  • Intenté cambiar el título clickbait usando la propia formulación del artículo
    Si se puede encontrar una frase más representativa en el artículo, se puede volver a cambiar
    Esto sigue la guía de títulos de HN: “usar el título original, salvo cuando sea engañoso o sensacionalista”: https://news.ycombinator.com/newsguidelines.html
  • No estoy de acuerdo con la premisa del artículo. UDP no existe por la falta de confiabilidad en sí, sino que es un compromiso en el que se obtiene velocidad y eficiencia a cambio de elegir entrega de mejor esfuerzo en vez de garantías
    Según la aplicación, puede tener sentido
    Por ejemplo, en un juego multijugador en tiempo real, si el procesamiento se queda atrás, los elementos atrasados ya no importan porque el estado del juego ya cambió
    En aplicaciones de trading de alta velocidad, en ciertas situaciones también importa solo el dato de mercado más reciente, no lo que pasó hace 100 ms
    • Esa no es la premisa del artículo, sino una creencia común que el autor corrige enseguida
      El artículo también pone como ejemplos adecuados para UDP los juegos y el video en vivo
    • Si sigues leyendo, el artículo básicamente dice eso
      La estructura es presentar primero la “creencia común” y luego refutarla
  • Las cosas que deberían estar basadas en datagramas son el descubrimiento local, el broadcast y la encapsulación de paquetes
    Por ejemplo, entran ahí DHCP, SLAAC, UPnP, mDNS, tinc y BitTorrent como descubrimiento local; el broadcast como streaming en redes locales; y WireGuard, IPSec, OpenVPN y VLAN como encapsulación
    • Un caso que falta es el de medios en tiempo real
      No solo la retransmisión, sino incluso el buffering para reordenar paquetes aumenta la latencia, así que es preferible tolerar las pérdidas mediante corrección de errores u ocultamiento de pérdida de paquetes
    • Desde mi posición de no tener muchos conocimientos de redes de bajo nivel, me pregunto si alguien podría explicar por qué estos casos de uso necesitan datagramas
    • Los juegos también entran ahí
  • El título es un clickbait tonto, y el propio autor lo admite al principio
    UDP y TCP tienen comportamientos y compromisos distintos, y todo se reduce a entenderlos antes de elegir según el caso de uso
    No hace falta hacer de guardián con frases tipo “nunca hagas X”
    • A menos que el asterisco antes de “never” se haya agregado en los 10 minutos posteriores a la publicación del comentario, ese asterisco claramente indica que hay condiciones específicas
      Solo con ver el título queda bastante claro que no es un texto que intente impedirte usar UDP como guardián
      De hecho, al final del artículo el autor propone usar QUIC, que está basado en UDP
  • La mayoría de las aplicaciones y casos usarán conexiones basadas en sesiones, pero también hay usos para datagramas directos, así que no hay que tenerles miedo
    Claro que tendrás que encargarte personalmente de muchos más detalles
    Además, es una buena forma de aprender los aspectos de bajo nivel de las redes
    • La SteamNetworkingMessages API para desarrollo de juegos permite usar bien este enfoque en ese caso de uso sin tener que preocuparse por los detalles internos