En esta página se describen los métodos para calcular los ajustes correctos para reducir la latencia de las conexiones TCP en escenarios Google Cloud y híbridos. Esta página también te ayuda a entender cómo mejorar la latencia de conexión entre procesos en Google Cloud.
La arquitectura de microservicios moderna recomienda que los desarrolladores creen servicios pequeños con una sola responsabilidad. Los servicios deben comunicarse mediante TCP o UDP, en función de las expectativas de fiabilidad del sistema. Por lo tanto, es fundamental que los sistemas basados en microservicios se comuniquen con fiabilidad y baja latencia.
Google Cloud ofrece fiabilidad y baja latencia gracias a su red global, lo que significa que los usuarios de tu aplicación también pueden llegar a todo el mundo. Una red global significa que creas una red de nube privada virtual (VPC) que abarca regiones y zonas. Las aplicaciones pueden conectarse entre sí en diferentes regiones y zonas sin salir nunca de la red de Google Cloud .
Las aplicaciones que se han escrito para un entorno de centro de datos tradicional pueden mostrar un rendimiento lento cuando se mueven 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 deberse a varios factores. Este artículo se centra en las latencias de ida y vuelta y en cómo afecta la latencia al rendimiento de TCP en las aplicaciones que transfieren una cantidad considerable de datos a través de cualquier parte de la red.
Optimizar el rendimiento de TCP
El problema: latencia y comportamiento de TCP
TCP usa un mecanismo de ventanas para evitar que un remitente rápido sobrepase a un receptor lento. El receptor anuncia la cantidad de datos que debe enviar el remitente antes de que este tenga que esperar a que el receptor actualice la ventana. Por lo tanto, 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 a la espera de la aplicación.
La ventana TCP permite usar la memoria de forma eficiente en los sistemas de envío y recepción. A medida que la aplicación receptora consume datos, se envían actualizaciones de la ventana al remitente. La actualización de la ventana más rápida posible es de un viaje de ida y vuelta, lo que da lugar a la siguiente fórmula para uno de los límites del rendimiento de la transferencia masiva de una conexión TCP:
El rendimiento es <= tamaño de la ventana/latencia del tiempo de ida y vuelta (RTT)
En el diseño original de TCP, esta ventana tiene un tamaño máximo de 65.535 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 poder enviar más datos.
Cambios en TCP desde su introducción
Desde que se introdujo TCP, algunas de sus funciones clave han cambiado:
- Las velocidades de red típicas 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 provocaron un uso ineficiente de los recursos de red. Un remitente enviaría una ventana de datos a la mejor velocidad posible en las condiciones de red y, a continuación, permanecería inactivo durante un tiempo considerable mientras espera la actualización de la ventana TCP. El resultado del segundo cambio es que los remitentes y los destinatarios pueden usar más memoria para las redes, lo que soluciona la limitación que se ha producido con el primer cambio.
En el siguiente diagrama se ilustra este intercambio.
El remitente no puede utilizar la red por completo 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, se pueden incluir más datos en el canal (red) y, a medida que el canal se alarga, se tarda más en confirmar la recepción de los datos. Esta relación se conoce como producto de ancho de banda y latencia (BDP). Se calcula multiplicando el ancho de banda por el tiempo de ida y vuelta (RTT), lo que da como resultado un valor que especifica el número óptimo de bits que se deben enviar para llenar el canal. La fórmula es la siguiente:
BDP (bits) = ancho de banda (bits/segundo) * RTT (segundos)
El BDP calculado se usa 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. En el caso del tamaño de la ventana, usa el valor del tamaño de la ventana TCP original (65.535 bytes). Este valor no se acerca a la capacidad de ancho de banda. El rendimiento máximo de TCP posible en este enlace es el siguiente:
(65.535 bytes * 8 bits/byte) = ancho de banda * 0,030 segundos
ancho de banda = (65.535 bytes * 8 bits/byte) / 0,030 segundos
ancho de banda = 524.280 bits / 0,030 segundos
ancho de banda = 17.476.000 bits/segundo
Dicho de otro modo, estos valores dan como resultado un rendimiento ligeramente superior a 17 Mbits por segundo, que es una pequeña parte de la capacidad de 10 Gbps de la red.
La solución: escalado 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 de TCP, se introdujeron extensiones en el 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, es decir, casi 1 GiB. Esta función se describe en el 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, a continuación, 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 comprobar si la función está habilitada en sistemas basados en Linux, usa el siguiente comando:
sudo sysctl net.ipv4.tcp_window_scaling
Todas las máquinas virtuales Linux tienen esta función habilitada de forma predeterminada. Google Cloud Si se devuelve el valor 1
, significa que la opción está habilitada. Si la función está inhabilitada, puedes habilitarla con el siguiente comando:
sudo sysctl -w net.ipv4.tcp_window_scaling=1
Rendimiento con un tamaño de ventana mayor
Puedes usar el ejemplo anterior para mostrar las ventajas de tener un escalado de ventanas. Como antes, supongamos que la red es de 10 Gbps y tiene una latencia de 30 milisegundos. A continuación, calcula el nuevo tamaño de la ventana con esta fórmula:
(Velocidad de enlace * latencia) / 8 bits = tamaño de la ventana
Si introduces los números de ejemplo, obtendrás lo siguiente:
(10 Gbps * 30 ms/1000 seg) / 8 bits/byte = tamaño de la ventana
(10.000 Mbps * 0,030 segundos) / 8 bits/byte = 37,5 MB
Si aumenta 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 cercano a la capacidad de la red. Por supuesto, hay muchos otros factores que pueden limitar el rendimiento, como la sobrecarga del sistema, el tamaño medio de los paquetes y el número de otros flujos que comparten el enlace. Sin embargo, como puedes ver, el tamaño de la ventana mitiga considerablemente los límites impuestos por el tamaño de la ventana anterior.
Configurar los parámetros ajustables 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 sysctl(8)
ajustes:
net.core.rmem_max
net.core.wmem_max
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem
Los dos primeros parámetros ajustables afectan al tamaño máximo de la ventana TCP de las aplicaciones que intentan controlar directamente el tamaño de la ventana TCP, limitando la solicitud de las aplicaciones a esos valores. Los dos últimos parámetros ajustables afectan al tamaño de la ventana TCP de las aplicaciones que permiten que el ajuste automático de Linux haga el trabajo.
El valor óptimo del tamaño de la ventana depende de tus circunstancias específicas, pero un punto de partida es el BDP (producto de ancho de banda y latencia) más grande de la ruta o las rutas por las que esperas que el sistema envíe datos. En ese caso, puedes definir los parámetros ajustables siguiendo estos pasos:
- Asegúrate de tener privilegios de superusuario.
Obtiene la configuración actual del búfer. Guarda estos ajustes por si quieres deshacer los cambios.
sudo sysctl -a | grep mem
Define una variable de entorno con el nuevo tamaño de ventana TCP que quieras usar:
MaxExpectedPathBDP=8388608
Define el tamaño máximo del búfer de recepción del SO para todos los tipos de conexiones:
sudo sysctl -w net.core.rmem_max=$MaxExpectedPathBDP
Define el tamaño máximo del búfer de envío del SO para todos los tipos de conexiones:
sudo sysctl -w net.core.wmem_max=$MaxExpectedPathBDP
Defina los ajustes del búfer de memoria de recepción de TCP (
tcp_rmem
):sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 $MaxExpectedPathBDP"
El ajuste
tcp_rmem
admite tres valores:- Tamaño mínimo del búfer de recepción que se puede asignar a un socket TCP.
En este ejemplo, el valor es
4096
bytes. - Tamaño predeterminado del búfer de recepción, que también anula el valor
/proc/sys/net/core/rmem_default
que usan otros protocolos. En el ejemplo, el valor es de87380
bytes. - Tamaño máximo del búfer de recepción que se puede asignar a un socket TCP.
En el ejemplo, se ha definido el valor que has configurado anteriormente (
8388608
bytes).
- Tamaño mínimo del búfer de recepción que se puede asignar a un socket TCP.
En este ejemplo, el valor es
Define los ajustes del búfer de memoria de envío de TCP (
tcp_wmem
):sudo sysctl -w net.ipv4.tcp_wmem="4096 16384 $MaxExpectedPathBDP"
El ajuste
tcp_wmem
admite tres valores:- Espacio mínimo del búfer de envío de TCP disponible para un único socket TCP.
- Espacio de búfer predeterminado permitido para un único socket TCP.
- El espacio máximo del búfer de envío de TCP.
Define los parámetros ajustables para que las conexiones posteriores usen los valores que hayas especificado:
sudo sysctl -w net.ipv4.route.flush=1
Para que estos ajustes se mantengan después de reiniciar el dispositivo, añade los comandos que hayas definido 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'
Prueba de TTR con un tamaño de ventana actualizado
Cuando TCP tiene un tamaño de ventana lo suficientemente grande como para usar el BDP, la situación cambia, como se muestra en el siguiente diagrama:
El tamaño de la ventana TCP siempre se puede adaptar en función de los recursos disponibles para el proceso en cuestión y el algoritmo TCP que se esté usando. Como se muestra en el diagrama, el escalado de ventanas 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 probarlo tú mismo. En primer lugar, asegúrate de haber cambiado el tamaño de la ventana TCP en tu ordenador local y en un ordenador remoto configurando los parámetros ajustables en ambos ordenadores. A continuación, ejecuta 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 con datos aleatorios. El segundo comando copia ese archivo de tu máquina local a una máquina remota.
Fíjate en el resultado del comando scp
en la consola, que muestra el ancho de banda en Kbps.
Deberías observar una diferencia considerable en los resultados antes y después de los cambios en el tamaño de la ventana TCP.
Optimizar la resiliencia de la red TCP mediante Protective ReRoute
Protective ReRoute (PRR) es una técnica basada en el host para enrutar paquetes en torno a los fallos de una red multipath. Google implementa PRR en toda la flota y complementa los mecanismos de resiliencia de red estándar para mejorar la disponibilidad general de la red.
La PRR está disponible para los clientes de Google Cloud en dos modos: modo hipervisor y modo invitado. Todos los clientes Google Cloud obtienen automáticamente la PRR en modo hipervisor sin tener que hacer nada.
El PRR en modo hipervisor protege la gran mayoría del tráfico, con algunas excepciones:
Si una instancia tiene una gran dispersión de tráfico (por ejemplo, si una instancia envía activamente paquetes a miles de instancias de otras regiones al mismo tiempo), no todos los paquetes estarán protegidos.
El PRR en modo hipervisor protege segmentos clave de la ruta de red, pero no es totalmente de extremo a extremo.
La PRR en modo hipervisor reacciona en cuestión de segundos.
El PRR del modo Invitado se puede usar en aplicaciones críticas que sean especialmente sensibles a eventos de red de corta duración, que tengan patrones de difusión amplios, que sean muy sensibles a la pérdida de paquetes o que requieran el tiempo de recuperación de la red más rápido posible (a escala de tiempo de RTT). Puedes adoptar el PRR del modo Invitado si cumples las siguientes condiciones:
- La instancia de proceso debe ejecutar Linux con el kernel 4.20 o una versión posterior. Para comprobar la versión del kernel de Linux, ejecuta el comando
uname -r
en la instancia de computación. - Debes habilitar lo siguiente:
sysctl
/proc/sys/net/ipv6/auto_flowlabels
. Estasysctl
suele estar habilitada de forma predeterminada. - Si se usa con la interfaz de red VirtIO, solo se protegerá el tráfico de red IPv6.
- Si se usa con la interfaz de red gVNIC, se protege el tráfico de red IPv4 e IPv6.
Siguientes pasos
- Consulta la entrada de blog sobre los 5 pasos para mejorar el rendimiento de las redes Google Cloud .
- Consulte información sobre los productos de redes globales.
- Consulta más información sobre los niveles de red en Google Cloud.
- Consulta cómo comparar el rendimiento de la red.