Optimización TCP para el rendimiento de la red


Esta página describe métodos para calcular la configuración correcta para disminuir la latencia de sus conexiones TCP en Google Cloud y escenarios híbridos. Esta página también le ayuda a comprender formas de mejorar la latencia de conexión entre procesos dentro de Google Cloud.

La arquitectura de microservicios moderna aboga por que los desarrolladores creen pequeños servicios con una única responsabilidad. Los servicios deben comunicarse mediante TCP o UDP, según las expectativas de confiabilidad del sistema. Por lo tanto, es fundamental que los sistemas basados ​​en microservicios se comuniquen con confiabilidad y baja latencia.

Google Cloud proporciona confiabilidad y baja latencia al proporcionar una red global , lo que significa que los usuarios de su aplicación también pueden globalizarse. Tener una red global significa que usted crea una red de Nube Privada Virtual (VPC) que abarca regiones y zonas . Las aplicaciones pueden conectarse entre sí a través de regiones y zonas sin tener que salir del Google Cloud red.

Las aplicaciones que se han escrito para un entorno de centro de datos tradicional pueden presentar un rendimiento lento cuando se trasladan a un entorno de nube híbrida, es decir, cuando algunos de los componentes de la aplicación se ejecutan en un centro de datos corporativo y otros se ejecutan en la nube. El rendimiento lento puede ser el resultado de varios factores. Este artículo se centra en las latencias de ida y vuelta y en cómo la latencia afecta el rendimiento de TCP en aplicaciones que mueven una cantidad considerable de datos a través de cualquier parte de la red.

El problema: latencia y comportamiento de TCP

TCP utiliza un mecanismo de ventanas para evitar que un remitente rápido sobrepase a un receptor lento. El receptor anuncia cuántos datos debe enviar el remitente antes de que deba esperar una actualización de la ventana del receptor. Como resultado, si una aplicación receptora no puede recibir datos en la conexión, hay un límite en la cantidad de datos que se pueden poner en cola esperando a la aplicación.

La ventana TCP permite un uso eficiente de la memoria en los sistemas de envío y recepción. A medida que la aplicación receptora consume datos, las actualizaciones de la ventana se envían al remitente. Lo más rápido que puede ocurrir la actualización de la ventana es en un viaje de ida y vuelta, lo que lleva a la siguiente fórmula para uno de los límites del rendimiento de transferencia masiva de una conexión TCP:

Rendimiento <= tamaño de ventana / latencia de tiempo de ida y vuelta (RTT)

En el diseño original de TCP, esta ventana tiene un tamaño máximo de 65535 bytes (64 KiB - 1). Esta era la cantidad máxima de datos que el remitente podía enviar antes de recibir una actualización de la ventana para permitir que se enviaran más datos.

Cambios en TCP desde su introducción

Desde que se introdujo TCP, algunas características clave han cambiado:

  • Las velocidades típicas de la red han aumentado en cuatro órdenes de magnitud.
  • La memoria típica de un sistema ha aumentado en cuatro órdenes de magnitud.

El resultado del primer cambio es que los tamaños de ventana TCP originales condujeron a un uso ineficiente de los recursos de la red. Un remitente enviaría datos de una ventana a la mejor velocidad posible en las condiciones de la red y luego permanecería inactivo durante un período de tiempo considerable mientras espera la actualización de la ventana TCP. El resultado del segundo cambio es que los remitentes y receptores pueden usar más memoria para la creación de redes para abordar la limitación expuesta por el primer cambio.

El siguiente diagrama ilustra este intercambio.

El remitente envía solo 64 KB de datos y pasa mucho tiempo esperando después del envío antes de recibir una actualización de la ventana

El remitente no puede utilizar completamente la red porque está esperando la actualización de la ventana TCP antes de enviar datos adicionales.

Enviar más datos a la vez

La solución es enviar más datos a la vez. A medida que aumenta el ancho de banda de la red, pueden caber más datos en la tubería (red) y, a medida que la tubería se hace más larga, se necesita más tiempo para acusar recibo de los datos. Esta relación se conoce como producto de retardo de ancho de banda (BDP). Esto se calcula como el ancho de banda multiplicado por el tiempo de ida y vuelta (RTT), lo que da como resultado un valor que especifica la cantidad óptima de bits a enviar para llenar la tubería. La fórmula es esta:

BDP (bits) = ancho de banda (bits/segundo) * RTT (segundos)

El BDP calculado se utiliza como tamaño de ventana TCP para la optimización.

Por ejemplo, imagina que tienes una red de 10 Gbps con un RTT de 30 milisegundos. Para el tamaño de la ventana, utilice el valor del tamaño de la ventana TCP original (65535 bytes). Este valor no se acerca a aprovechar la capacidad del ancho de banda. El rendimiento máximo de TCP posible en este enlace es el siguiente:

(65535 bytes * 8 bits/byte) = ancho de banda * 0,030 segundos
ancho de banda = (65535 bytes * 8 bits/byte) / 0,030 segundos
ancho de banda = 524280 bits / 0,030 segundos
ancho de banda = 17476000 bits/segundo

Para decirlo de otra manera, estos valores dan como resultado un rendimiento de poco más de 17 Mbits por segundo, que es una pequeña fracción de la capacidad de 10 Gbps de la red.

La solución: escalamiento del tamaño de la ventana TCP

Para resolver las limitaciones de rendimiento impuestas por el diseño original del tamaño de la ventana TCP, se introdujeron extensiones al protocolo TCP que permiten escalar el tamaño de la ventana a valores mucho mayores. El escalado de ventanas admite ventanas de hasta 1.073.725.440 bytes, o casi 1 GiB. Esta característica se describe en RFC 7323 como opción de escala de ventana TCP .

Las extensiones de escala de ventana amplían la definición de la ventana TCP para usar 30 bits y luego usan un factor de escala implícito para transportar este valor de 30 bits en el campo de ventana de 16 bits del encabezado TCP. Para ver si la función está habilitada en sistemas basados ​​en Linux, use el siguiente comando:

sudo sysctl net.ipv4.tcp_window_scaling

Todo Google Cloud Las máquinas virtuales Linux tienen esta característica habilitada de forma predeterminada. Un valor de retorno de 1 indica que la opción está habilitada. Si la función está deshabilitada, puede habilitarla usando el siguiente comando:

sudo sysctl -w net.ipv4.tcp_window_scaling=1

Rendimiento con un tamaño de ventana más grande

Puede utilizar el ejemplo anterior para mostrar el beneficio de tener escalado de ventana. Como antes, supongamos una red de 10 Gbps con una latencia de 30 milisegundos y luego calcule un nuevo tamaño de ventana usando esta fórmula:

(Velocidad de enlace * latencia) / 8 bits = tamaño de ventana

Si ingresa los números de ejemplo, obtendrá esto:

(10 Gbps * 30 ms/1000 s) / 8 bits/byte = tamaño de ventana
(10000 Mbps * 0,030 segundos) / 8 bits/byte = 37,5 MB

Aumentar el tamaño de la ventana TCP a 37 MB puede aumentar el límite teórico del rendimiento de la transferencia masiva de TCP a un valor que se acerque a la capacidad de la red. Por supuesto, muchos otros factores pueden limitar el rendimiento, incluida la sobrecarga del sistema, el tamaño promedio de los paquetes y la cantidad de otros flujos que comparten el enlace, pero como puede ver, el tamaño de la ventana mitiga sustancialmente los límites impuestos por el tamaño de ventana limitado anterior.

Configuración de sintonizables de Linux para cambiar el tamaño de la ventana TCP

En Linux, el tamaño de la ventana TCP se ve afectado por los siguientes parámetros optimizables sysctl(8) :

net.core.rmem_max
net.core.wmem_max
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem

Los dos primeros parámetros ajustables afectan el tamaño máximo de la ventana TCP para las aplicaciones que intentan controlar el tamaño de la ventana TCP directamente, limitando la solicitud de las aplicaciones a no más de esos valores. Los dos segundos parámetros ajustables afectan el tamaño de la ventana TCP para las aplicaciones que permiten que el ajuste automático de Linux haga el trabajo.

El valor óptimo del tamaño de ventana depende de sus circunstancias específicas, pero un punto de partida es el BDP (producto de retardo de ancho de banda) más grande para la ruta o rutas por las que espera que el sistema envíe datos. En ese caso, desea configurar los sintonizables siguiendo los siguientes pasos:

  1. Asegúrese de tener privilegios de root.
  2. Obtenga la configuración actual del búfer. Guarde esta configuración en caso de que desee revertir estos cambios.

    sudo sysctl -a | grep mem
    
  3. Establezca una variable de entorno para el nuevo tamaño de ventana TCP que desea utilizar:

    MaxExpectedPathBDP=8388608
    
  4. Establezca el tamaño máximo del búfer de recepción del sistema operativo para todos los tipos de conexiones:

    sudo sysctl -w net.core.rmem_max=$MaxExpectedPathBDP
    
  5. Establezca el tamaño máximo del búfer de envío del sistema operativo para todos los tipos de conexiones:

    sudo sysctl -w net.core.wmem_max=$MaxExpectedPathBDP
    
  6. Establezca la configuración del búfer de memoria de recepción TCP ( tcp_rmem ):

    sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 $MaxExpectedPathBDP"
    

    La configuración tcp_rmem toma tres valores:

    • El tamaño mínimo del búfer de recepción que se puede asignar para un socket TCP. En este ejemplo, el valor es 4096 bytes.
    • El tamaño del búfer de recepción predeterminado, que también anula el valor /proc/sys/net/core/rmem_default utilizado por otros protocolos. En el ejemplo, el valor es 87380 bytes.
    • El tamaño máximo del búfer de recepción que se puede asignar para un socket TCP. En el ejemplo, esto se establece en el valor que estableció anteriormente ( 8388608 bytes).
  7. Establezca la configuración del búfer de memoria de envío TCP ( tcp_wmem ):

    sudo sysctl -w net.ipv4.tcp_wmem="4096 16384 $MaxExpectedPathBDP"
    

    La configuración tcp_wmem toma tres valores:

    • El espacio mínimo de búfer de envío TCP disponible para un único socket TCP.
    • El espacio de búfer predeterminado permitido para un único socket TCP.
    • El espacio máximo del búfer de envío TCP.
  8. Configure los parámetros ajustables para que las conexiones posteriores utilicen los valores que especificó:

    sudo sysctl -w net.ipv4.route.flush=1
    

Para conservar estas configuraciones durante los reinicios, agregue los comandos que configuró anteriormente al archivo /etc/sysctl.conf :

sudo bash -c 'cat << EOF >> /etc/sysctl.conf
net.core.rmem_max=8388608
net.core.wmem_max=8388608
net.ipv4.tcp_rmem=4096 87380 8388608
net.ipv4.tcp_wmem=4096 16384 8388608
net.ipv4.route.flush=1
EOF'

Probando RTT con un tamaño de ventana actualizado

Cuando TCP tiene un tamaño de ventana lo suficientemente grande para utilizar BDP, la imagen cambia, como se muestra en el siguiente diagrama:

El remitente envía una gran cantidad de datos a la vez y pasa muy poco tiempo esperando una actualización de la ventana.

El tamaño de la ventana TCP siempre se puede adaptar en función de los recursos disponibles para el proceso involucrado y el algoritmo TCP en uso. Como muestra el diagrama, el escalado de ventana permite que una conexión vaya mucho más allá del tamaño de ventana de 65 KiB definido en la especificación TCP original.

Puedes probar esto tú mismo. Primero, asegúrese de haber realizado cambios en el tamaño de la ventana TCP en su computadora local y en una computadora remota configurando los ajustes ajustables en ambas máquinas. Luego ejecute los siguientes comandos:.

dd if=/dev/urandom of=sample.txt bs=1M count=1024 iflag=fullblock
scp sample.txt your_username@remotehost.com:/some/remote/directory

El primer comando crea un archivo sample.txt de 1 GB que tiene datos aleatorios. El segundo comando copia ese archivo de su máquina local a una máquina remota.

Tenga en cuenta la salida del comando scp en la consola, que muestra el ancho de banda en Kbps. Debería ver una diferencia considerable en los resultados antes y después de que cambie el tamaño de la ventana TCP.

¿Qué sigue?