Articulo de referencia

El algoritmo de Nagle

El algoritmo de Nagle es un método para mejorar la eficiencia de las redes TCP/IP al reducir la cantidad de paquetes que deben enviarse a través de la red. Fue definido por John...

El algoritmo de Nagle es un método para mejorar la eficiencia de las redes TCP/IP al reducir la cantidad de paquetes que deben enviarse a través de la red. Fue definido por John Nagle mientras trabajaba para Ford Aerospace . Se publicó en 1984 como una Solicitud de Comentarios (RFC) con el título Control de Congestión en Redes IP/TCP en la RFC 896 . 

El RFC describe lo que Nagle denomina el "problema de los paquetes pequeños", donde una aplicación emite repetidamente datos en pequeños fragmentos, frecuentemente de tan solo 1 byte . Dado que los paquetes TCP tienen una cabecera de 40 bytes (20 bytes para TCP y 20 bytes para IPv4 ), esto resulta en un paquete de 41 bytes para 1 byte de información útil, lo que supone una sobrecarga enorme. Esta situación se da a menudo en las sesiones de Telnet , donde la mayoría de las pulsaciones de teclas generan un único byte de datos que se transmite inmediatamente. Peor aún, en enlaces lentos, muchos de estos paquetes pueden estar en tránsito simultáneamente, lo que podría provocar un colapso por congestión .

El algoritmo de Nagle funciona combinando varios mensajes pequeños que se envían simultáneamente. En concreto, mientras haya un paquete enviado del que el remitente no haya recibido confirmación, este deberá seguir almacenando en búfer su salida hasta completar un paquete entero, lo que permitirá enviar toda la salida a la vez.

Algoritmo

El RFC define el algoritmo como

Inhibir el envío de nuevos segmentos TCP cuando lleguen nuevos datos salientes del usuario si algún dato transmitido previamente en la conexión permanece sin confirmar.

Donde MSS es el tamaño máximo del segmento , el segmento más grande que se puede enviar en esta conexión, y el tamaño de la ventana es la ventana actualmente aceptable de datos no confirmados, esto se puede escribir en pseudocódigo como

Si hay nuevos datos para enviar, entonces si el tamaño de la ventana es ≥ MSS y los datos disponibles son ≥ MSS , entonces Enviar el segmento MSS completo ahora de lo contrario , si todavía hay datos no confirmados en la canalización , entonces poner en cola los datos en el búfer hasta que se reciba una confirmación. demás enviar datos inmediatamente fin si fin si fin si

Interacción con ACK retardado

Este algoritmo interactúa negativamente con las confirmaciones diferidas de TCP (ACK diferido), una función introducida en TCP aproximadamente al mismo tiempo, a principios de la década de 1980, pero por un grupo diferente. Con ambos algoritmos habilitados, las aplicaciones que realizan dos escrituras sucesivas en una conexión TCP, seguidas de una lectura que no se completará hasta que los datos de la segunda escritura hayan llegado a su destino, experimentan una demora constante de hasta 500 milisegundos, conocida como " detección de ACK ". Se recomienda deshabilitar cualquiera de los dos, aunque tradicionalmente es más fácil deshabilitar Nagle, ya que existe un interruptor para ello en aplicaciones en tiempo real.

Una solución recomendada por Nagle, que evita que el algoritmo envíe paquetes prematuros, consiste en almacenar en búfer las escrituras de la aplicación y luego vaciar el búfer: [ 1 ]

La solución a nivel de usuario consiste en evitar secuencias de escritura-escritura-lectura en sockets. Escribir-leer-escritura-lectura funciona bien. Escribir-escribir-escritura también. Pero escribir-escribir-lectura es perjudicial. Por lo tanto, si es posible, almacene en búfer sus pequeñas escrituras a TCP y envíelas todas a la vez. Usar el paquete de E/S estándar de UNIX y vaciar el búfer de escritura antes de cada lectura suele funcionar.

Nagle considera que los ACK retardados son una "mala idea", ya que la capa de aplicación no suele responder dentro de la ventana de retardo (lo que permitiría combinar el ACK con el paquete de respuesta). [ 2 ] Para casos de uso típicos (no en tiempo real), recomienda deshabilitar los ACK retardados en lugar de deshabilitar su algoritmo, ya que los ACK "rápidos" no generan tanta sobrecarga como muchos paquetes pequeños para la misma mejora en el tiempo de ida y vuelta. [ 3 ]

Deshabilitar Nagle o el ACK retardado

Las implementaciones de TCP suelen proporcionar a las aplicaciones una interfaz para deshabilitar el algoritmo de Nagle. Esto se denomina normalmente TCP_NODELAYopción. En Microsoft Windows, el TcpNoDelayinterruptor del registro determina el valor predeterminado. TCP_NODELAYEstá presente desde la pila TCP/IP en 4.2BSD de 1983, una pila con muchos descendientes. [ 4 ]

La interfaz para deshabilitar el ACK retardado no es consistente entre sistemas. La TCP_QUICKACKbandera está disponible en Linux desde 2001 (2.4.4) y potencialmente en Windows, donde la interfaz oficial es SIO_TCP_SET_ACK_FREQUENCY. [ 5 ]

Al establecer el valor TcpAckFrequencyen 1 en el registro de Windows, se desactiva el ACK retardado de forma predeterminada. [ 6 ] En FreeBSD, la entrada sysctl net.inet.tcp.delayed_ack controla el comportamiento predeterminado. [ 4 ] No existe tal interruptor en Linux. [ 7 ]

Caja de escritura grande

La interacción entre el ACK retardado y Nagle también se extiende a escrituras más grandes. Si los datos en una sola escritura abarcan 2 n paquetes, donde hay 2 n -1 segmentos TCP de tamaño completo seguidos de un segmento TCP parcial, el algoritmo Nagle original retendría el último paquete, esperando a que se envíen más datos (para completar el paquete) o el ACK del paquete anterior (que indica que todos los paquetes anteriores han salido de la red). Un ACK retardado añadiría, de nuevo, un máximo de 500  ms antes de que se envíe el último paquete. [ 8 ] Este comportamiento limita el rendimiento para protocolos de aplicación de solicitud-respuesta de parada y espera sin segmentación, como HTTP con conexión persistente. [ 9 ]

La modificación de Minshall al algoritmo de Nagle hace que este siempre envíe si el último paquete es de tamaño completo , esperando una confirmación solo cuando el último paquete es parcial. El objetivo era reducir el incentivo para deshabilitar Nagle solucionando esta penalización por escritura de gran tamaño. [ 10 ] Nuevamente, deshabilitar la confirmación diferida en el extremo receptor eliminaría el problema por completo.

Interacciones con sistemas en tiempo real

Las aplicaciones que esperan respuestas en tiempo real y baja latencia pueden reaccionar mal al algoritmo de Nagle. Aplicaciones como los videojuegos multijugador en red o el movimiento del ratón en un sistema operativo controlado remotamente esperan que las acciones se envíen inmediatamente, mientras que el algoritmo retrasa deliberadamente la transmisión, aumentando la eficiencia del ancho de banda a costa de la latencia unidireccional . [ 3 ] Por esta razón, las aplicaciones con transmisiones sensibles al tiempo y de bajo ancho de banda suelen utilizar TCP_NODELAYpara evitar el retardo ACK retardado de Nagle. [ 11 ]

Otra opción es utilizar UDP en su lugar.

Implementación de sistemas operativos

La mayoría de los sistemas operativos modernos implementan los algoritmos de Nagle. En AIX, [ 12 ] y Windows está habilitado de forma predeterminada y se puede deshabilitar por socket utilizando la TCP_NODELAYopción.

Referencias

  1. John Nagle (19 de enero de 2006), Mejorando el rendimiento de los sockets en Linux , Slashdot
  2. Nagle, John. "Suspiro. Si haces transferencias masivas de archivos, nunca te encuentras con ese problema. (respuesta 9048947)" . Hacker News . Consultado el 9 de mayo de 2018 .
  3. 1 2 Nagle, John. "Ese temporizador de retardo ACK fijo de 200 ms fue un error terrible. ¿Por qué 200 ms? Tiempo de reacción humana. (respuesta 9050645)" . Hacker News . Recuperado el 9 de mayo de 2018. [...] Uno de los pocos casos legítimos para desactivar el algoritmo de Nagle es para un juego FPS que se ejecuta en la red. Allí, la latencia unidireccional importa; enviar tus disparos y movimientos al servidor antes que los otros jugadores afecta la jugabilidad.
  4. 1 2Manual de interfaces del kernel de FreeBSDtcp(4)  
  5. "sockets - C++ Deshabilitar el ACK diferido en Windows" . Stack Overflow .
  6. "Nueva entrada de registro para controlar el comportamiento de la confirmación TCP (ACK) en Windows XP y en Windows Server 2003" . 23 de febrero de 2023.
  7. Manual del programador de Linux – Descripción general, convenciones y miscelánea de Manned.orgtcp(7)  
  8. "Problemas de rendimiento de TCP causados ​​por la interacción entre el algoritmo de Nagle y el ACK retardado" . Stuartcheshire.org . Consultado el 14 de noviembre de 2012 .
  9. Heidemann, John (abril de 1997). "Interacciones de rendimiento entre implementaciones de P-HTTP y TCP" . ACM SIGCOMM Computer Communication Review . 27 (2). ACM: 65–73 . doi : 10.1145/263876.263886 . S2CID 6992265 . 
  10. Una modificación propuesta al algoritmo de Nagle . IETF . 1999. ID draft-minshall-nagle.
  11. Error 17868 : algunas aplicaciones Java son lentas en conexiones X remotas .
  12. " Centro de conocimiento de IBM" . www.ibm.com
  • Larry L. Peterson ; Bruce S. Davie (2007). Redes de computadoras: Un enfoque de sistemas (4.ª  ed.). Morgan Kaufmann. págs. 402–403 . ISBN  978-0-12-374013-7.
  • Retrasos de Nagle en el algoritmo de Nagle
  • El algoritmo de Nagle
  • Problemas de rendimiento de TCP causados ​​por la interacción entre el algoritmo de Nagle y el ACK retardado
  • Problemas de diseño: envío de pequeños segmentos de datos a través de TCP con Winsock.