La red global de Google Cloud proporciona alta confiabilidad y baja latencia, ya que conecta aplicaciones en regiones y zonas sin salir de la red de Google. Sin embargo, la configuración predeterminada de TCP/IP de Linux suele ajustarse para entornos locales y puede causar cuellos de botella en el rendimiento en la nube.
Para obtener el mejor rendimiento en Google Cloud, usa la configuración de TCP/IP de este documento, que está optimizada específicamente para el entorno de la nube.
La configuración que se menciona en este documento se probó para su uso en el entorno deGoogle Cloud . La configuración se aplica principalmente a las comunicaciones internas de las instancias y no necesariamente a la comunicación entre las instancias de Compute Engine y las direcciones externas.
Información sobre el límite de capacidad de procesamiento
TCP usa un mecanismo de "ventana" para administrar el flujo de datos entre un remitente y un receptor. La capacidad de procesamiento máxima que se puede alcanzar se rige por la siguiente relación:
Throughput <= window size / round-trip time (RTT) latency
En el diseño original de TCP, el tamaño máximo de la ventana se limita a 65,535 bytes (64 KiB - 1), lo que a menudo hace que las redes modernas de alta velocidad no se utilicen por completo, ya que el remitente espera actualizaciones de la ventana.
Secuencia de comandos de shell para optimizar el rendimiento de TCP
Se recomiendan los siguientes parámetros de configuración de TCP para mejorar el rendimiento:
- Reduce MinRTO: Se recupera más rápido de la pérdida de paquetes, ya que reduce los retrasos en la retransmisión.
- Habilita la administración de filas justa: Minimiza la congestión y las pérdidas debido a ráfagas de aplicaciones.
- Inhabilitar el inicio lento después de la inactividad: Reinicia la transferencia con la última velocidad de transferencia correcta conocida después de un período de inactividad de la conexión.
- Inhabilita el tren de ACK de TCP Cubic HyStart: Ignora los indicadores de congestión de falsos positivos cuando se aumenta la tasa de transferencia de datos.
- Aumenta los presupuestos de memoria de los sockets: Aumenta la cantidad máxima permitida de datos en tránsito por conexión.
- Habilita la descarga de recepción de hardware (GRO): Aumenta la eficiencia del procesamiento de recepción de TCP/IP para flujos grandes combinando datos en menos paquetes más grandes.
- Aumentar la MTU a 4,082 bytes: Aumenta la eficiencia de la transferencia para flujos de gran capacidad de procesamiento.
Puedes habilitar estos parámetros de configuración sugeridos con el siguiente secuencia de comandos de shell. Antes de ejecutar la secuencia de comandos, asegúrate de reemplazar eth0 por la interfaz de red principal de tu instancia de procesamiento.
# Set DEV to your primary network interface
DEV=eth0
# 1. Reduce MinRTO
sysctl -w net.ipv4.tcp_rto_min_us=5000
# 2. Enable Fair Queueing
tc qdisc replace dev $DEV root fq
# 3. Disable slow start after idle
sysctl -w net.ipv4.tcp_slow_start_after_idle=0
# 4. Disable TCP Cubic HyStart ACK train
echo 2 > /sys/module/tcp_cubic/parameters/hystart_detect
# 5. Increase socket memory budgets
echo 4194304 > /proc/sys/net/core/rmem_max
echo 4194304 > /proc/sys/net/core/wmem_max
echo 4194304 > /proc/sys/net/ipv4/tcp_notsent_lowat
echo "4096 262144 16777216" > /proc/sys/net/ipv4/tcp_rmem
echo "4096 262144 33554432" > /proc/sys/net/ipv4/tcp_wmem
# 6. Enable hardware GRO
ethtool -K $DEV rx-gro-hw on
En las siguientes secciones, se describe cada uno de los parámetros de configuración sugeridos con más detalle.
Reduce MinRTO
Recupérate más rápido de la pérdida de paquetes reduciendo los retrasos en la retransmisión.
El tiempo de espera de retransmisión (RTO) de TCP controla el tiempo que un remitente de TCP espera una señal de ACK antes de retransmitir. Linux inicializa el RTO en un segundo (según la sección 2.1 del RFC 6298) y, luego, lo ajusta con el tiempo al tiempo de ida y vuelta (RTT) más un margen de seguridad.
El RTO mínimo (MinRTO) implementa un límite inferior en este ajuste. Si la estimación del RTO es demasiado baja, puede generar retransmisiones espurias, en las que el remitente retransmite paquetes mientras la respuesta aún está en proceso.
El valor predeterminado de MinRTO es de 200 ms, que es innecesariamente conservador para las redes en la nube modernas. Se probó exhaustivamente un valor de 5 ms enGoogle Cloud y es un valor predeterminado seguro para las conexiones entre servidores Linux modernos en Google Cloud.
Otro factor son los ACK retrasados, en los que el par retrasa las respuestas de ACK. Esta demora permite agrupar los ACK en varios paquetes de datos o combinar un ACK con un paquete de datos en la dirección inversa. Los temporizadores de ACK retrasado se basan en el RTT, de manera similar al temporizador de RTO.
Reducir el MinRTO acelera la reparación de pérdidas en conexiones con un RTT bajo, como las conexiones dentro de una zona o región. Este ajuste no afecta el comportamiento de las conexiones que experimentan un RTT alto, ya que no cambia su RTT estimado.
Configuración de MinRTO
Puedes configurar MinRTO con uno de los siguientes métodos:
Usa
sysctl(Linux 6.11 y versiones posteriores):Puedes configurar el MinRTO predeterminado con un comando
sysctl:sysctl -w net.ipv4.tcp_rto_min_us=5000Usa
ip route(control por ruta o versiones de Linux anteriores a la 6.11):Como alternativa, para versiones anteriores de Linux o para el control por ruta, MinRTO se puede establecer por ruta:
ip route change default rto_min 5ms
El enfoque por ruta es preferible en entornos en los que las conexiones pueden salir Google Cloud o comunicarse con pilas de TCP/IP que no son de Linux. Estos sistemas pueden tener diferentes temporizadores de ACK retrasado. Para una implementación amplia en Internet pública, se recomienda mantener el parámetro de configuración predeterminado conservador de minRTO y aplicar el parámetro de configuración de 5 ms solo para las rutas dentro de la nube privada virtual de Google Cloud .
Habilita el encolamiento justo
Minimizar la congestión y la pérdida de paquetes causadas por ráfagas de aplicaciones
A diferencia de las colas FIFO (primero en entrar, primero en salir) estándar, la administración de colas equitativa (FQ) distribuye el ancho de banda de manera equitativa entre los diferentes flujos. También regula el tráfico, ya que permite que cada conexión TCP calcule su tasa y tiempo de entrega óptimos para cada paquete. Si FQ está presente, la pila de TCP depende de FQ para retener los paquetes hasta su tiempo de entrega óptimo. Este ritmo reduce las ráfagas dentro de un flujo, lo que, a su vez, minimiza las pérdidas y retransmisiones de paquetes.
Para establecer el modelador de tráfico de FQ como el modelador de tráfico del dispositivo de red, usa el siguiente comando tc (control de tráfico):
tc qdisc replace dev $DEV root fq
En instancias grandes con un ancho de banda de salida alto, es posible que el dispositivo de red tenga varias colas de transmisión. Para estas instancias, puede ser preferible fragmentar la adaptación del tráfico en las colas de transmisión instalando el adaptador de tráfico de Multi Queue (MQ). Este es un multiplexor que adjunta un modelador de tráfico independiente a cada cola de transmisión. Los modeladores de tráfico por fila reducen la contención en los bloqueos y las líneas de caché en las CPUs.
Inhabilita el inicio lento después de la inactividad
Mantener altas velocidades de transferencia después de que una conexión haya estado inactiva
Para evitar la congestión, las conexiones TCP comienzan enviando datos a una velocidad baja y, luego, aumentan la velocidad de forma exponencial hasta que se detecta la pérdida de paquetes. Esta fase inicial se conoce como Slow Start.
De forma predeterminada, TCP vuelve a la configuración conservadora de "Inicio lento" después de un período de inactividad. Un período de inactividad puede ser tan corto como un tiempo de espera de retransmisión (RTO), como se define en el RFC 2581. Si inhabilitas esta función, la conexión se reanudará de inmediato a la última buena velocidad conocida.
Cuando sea posible, las aplicaciones deben usar conexiones de larga duración en lugar de establecer conexiones repetidas con el mismo par. Esto evita el costo de establecer la conexión y mantiene la información de congestión. Sin embargo, incluso con conexiones de larga duración, después de un período de inactividad, TCP olvida la información de congestión de forma predeterminada y vuelve a la configuración conservadora inicial y a la fase de "inicio lento".
Para inhabilitar la función de inicio lento después de inactividad, usa el siguiente comando:
sysctl -w net.ipv4.tcp_slow_start_after_idle=0
Inhabilita el tren de ACK de HyStart de Cubic de TCP
Ignora los indicadores de congestión de falsos positivos para escalar rápidamente a tasas de transferencia altas.
La tasa de crecimiento exponencial de la fase de "Inicio lento" puede ser agresiva y, potencialmente, superar la tasa objetivo óptima. El inicio híbrido (HyStart) es un mecanismo adicional diseñado para salir de la fase de "inicio lento" antes, ya que usa dos indicadores clave de congestión:
- Demora del tiempo de ida y vuelta (RTT): Mide la demora de propagación de los paquetes a través de la red. Durante los períodos de congestión de la red, las colas de paquetes se acumulan en los vínculos de cuello de botella. Esto provoca que aumente el RTT, lo que puede indicar la presencia de congestión.
- Espaciado de ACK: Se basa en indicadores de que los paquetes se retrasan en un cuello de botella, pero se enfoca en los ACK de respuesta. Este mecanismo supone que, sin congestión, los ACK llegarán con el mismo espaciado que los paquetes de datos originales. Este patrón suele denominarse tren de ACK. Si los ACK se retrasan más allá de este patrón esperado, indica que podría haber congestión.
Para optimizar el rendimiento, inhabilita la detección de trenes de paquetes ACK y mantén habilitado el mecanismo de retraso del RTT.
echo 2 > /sys/module/tcp_cubic/parameters/hystart_detect
Aumenta los presupuestos de memoria de los sockets
Aumenta la capacidad de procesamiento máxima en vínculos con un RTT alto, ya que permite más datos en tránsito.
La cantidad de datos en tránsito es una función del ancho de banda y el retraso de propagación, y se conoce como el producto de retraso de ancho de banda (BDP). El BDP 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 para enviar y llenar la canalización:
BDP (bits) = bandwidth (bits/second) * RTT (seconds)
Todos los datos en tránsito deben permanecer almacenados en el búfer del remitente en caso de que deban retransmitirse. Los límites de memoria de los sockets TCP pueden limitar directamente el rendimiento alcanzable, ya que determinan la cantidad de datos en tránsito que se pueden almacenar en búfer.
En Linux, los límites de memoria de los sockets TCP se configuran con los siguientes parámetros de configuración de sysctl(8):
net.core.rmem_maxnet.core.wmem_maxnet.ipv4.tcp_rmemnet.ipv4.tcp_wmem
Estos límites de memoria de sockets TCP existen para evitar el uso de toda la memoria del sistema y provocar condiciones de memoria insuficiente (OOM), en especial en cargas de trabajo con muchas conexiones. Aumentar estos límites puede incrementar la capacidad de procesamiento, especialmente en rutas con un RTT alto. A menos que el recuento de conexiones sea de millones, no hay mucho riesgo en aumentar estos límites.
Estas variables establecen límites superiores en el tamaño del búfer de socket, no en la asignación directa de memoria. Aumentar estos valores no afecta la asignación de memoria real para las conexiones con un RTT bajo, como las que se encuentran dentro de una zona de Google Cloud .
Los primeros dos parámetros ajustables afectan el tamaño máximo de ventana de TCP para las aplicaciones que configuran el tamaño de ventana de TCP directamente, lo que hacen relativamente pocas aplicaciones. Estos límites determinan lo que una aplicación puede solicitar de forma explícita con las opciones de socket SO_RCVBUF y SO_SNDBUF.
Para las versiones de kernel de Linux 6.18 y posteriores, net.core.rmem_max y net.core.wmem_max tienen un valor predeterminado de 4 MB. Según años de experiencia, estos parámetros de configuración se consideran seguros. Para versiones anteriores de Linux, recomendamos aumentar estos límites a 4 MB en plataformas modernas:
echo 4194304 > /proc/sys/net/core/rmem_max
echo 4194304 > /proc/sys/net/core/wmem_max
El segundo conjunto de límites, net.ipv4.tcp_rmem y net.ipv4.tcp_wmem, administra los límites de ajuste automático del búfer de envío y recepción de TCP.
Cada uno de estos parámetros de configuración toma tres valores: tamaño mínimo, predeterminado inicial y máximo de la memoria del socket. Los valores máximos predeterminados suelen ser más conservadores de lo necesario en las plataformas modernas, por ejemplo:
tcp_rmem: 4096, 131072, 6291456tcp_wmem: 4096, 16384, 4194304
La pila de TCP ajusta automáticamente el tamaño de los búferes de envío y recepción de TCP según las estimaciones del RTT y la ventana de congestión. Un tamaño máximo de búfer de escritura de 4194304, o 4 MB, es pequeño para las conexiones con un RTT alto. Con un RTT de 100 ms, este parámetro de configuración limita la capacidad de procesamiento a 40 MB/s en el mejor de los casos. En lugar de intentar calcular qué valores usar, un enfoque más simple es usar valores predeterminados seguros para los servidores modernos que tienen muchos GB de RAM.
Como precaución adicional, recomendamos limitar la cantidad de datos que se pueden poner en cola en el socket, pero que aún no se enviaron. Si bien el objetivo de aumentar el valor de wmem máximo es permitir que haya más datos en tránsito, un proceso puede escribir en el socket más rápido de lo que TCP puede enviarlo, lo que provoca que se acumule una cola de datos no enviados en el host y se desperdicie memoria. Para evitar esto, limita la cantidad de datos que aún no se enviaron configurando tcp_notsent_lowat y, luego, aumenta el límite general de wmem para permitir búferes en tránsito más grandes.
A menos que un servidor tenga millones de conexiones, los siguientes parámetros de configuración deberían ser seguros. Sin embargo, si experimentas condiciones de memoria insuficiente con muchas conexiones, usa un tamaño de búfer máximo más bajo.
echo 4194304 > /proc/sys/net/ipv4/tcp_notsent_lowat
echo "4096 262144 16777216" > /proc/sys/net/ipv4/tcp_rmem
echo "4096 262144 33554432" > /proc/sys/net/ipv4/tcp_wmem
Habilita el GRO de hardware
Se aumentó la eficiencia del procesamiento de recepción de TCP/IP para flujos grandes. Reduce la sobrecarga de la CPU agrupando los paquetes recibidos
Para la mayoría de las operaciones de TCP/IP, el costo de los ciclos de CPU se ajusta según la tasa de paquetes, no la tasa de bytes. Para mitigar esta sobrecarga en la transmisión, los sistemas operativos modernos envían datos TCP a través de la ruta de transmisión en paquetes grandes que contienen varios segmentos TCP. Pueden tener un tamaño de hasta 64 KB o incluso cientos de kilobytes con BIG-TCP de Linux.
Estos paquetes grandes exceden el tamaño máximo de paquete en la red, la MTU. Esta optimización del sistema operativo se basa en la compatibilidad con dispositivos de red para dividir estos paquetes y enviarlos como una secuencia de paquetes más pequeños, cada uno con un solo segmento TCP. Esta compatibilidad, la descarga de segmentación TCP (TSO), está ampliamente disponible y habilitada de forma predeterminada.
En la recepción, los dispositivos GVNIC en plataformas de tercera generación y posteriores pueden realizar la operación inversa: almacenan en búfer brevemente los segmentos en el dispositivo para ver si llegan segmentos consecutivos y, si es así, los combinan y los reenvían como paquetes de varios segmentos al host. Esta función se conoce de diversas maneras, como Receive Segment Coalescing (RSC) en Windows, Large Receive Offload (LRO) o Hardware Generic Receive Offload (HW-GRO) en Linux. HW-GRO es un perfeccionamiento más estricto de LRO.
HW-GRO se puede habilitar de forma predeterminada sin problemas. Esto sucede con el tiempo cuando está disponible.
Mientras tanto, en las plataformas con dispositivos gVNIC que admiten la función, habilita HW-GRO con ethtool. Según la versión del kernel y del controlador, la función se anuncia como LRO o HW-GRO. La implementación es la misma, independientemente del nombre.
ethtool -K $DEV large-receive-offload on
ethtool -K $DEV rx-gro-hw on
Aumenta el tamaño de la MTU a 4,082 bytes
Aumenta la eficiencia de la transferencia de datos para los flujos de gran capacidad de procesamiento.
Aumentar el tamaño del paquete, de manera similar a las optimizaciones de TSO y HW-GRO, mejora la eficiencia de la transferencia, ya que la mayor parte del trabajo de procesamiento se realiza por paquete, no por byte.
Google Cloud Las redes de VPC pueden admitir paquetes de hasta 8,898 bytes, lo que es significativamente mayor que la MTU predeterminada de 1,460 bytes. Usar un tamaño de paquete de red más grande reduce los ciclos de CPU que se utilizan por byte de capacidad de procesamiento (rendimiento útil).
Consideraciones sobre el tamaño óptimo del paquete
Si bien los paquetes más grandes suelen ser mejores, la MTU máxima posible no siempre es la opción óptima. La eficiencia que se obtiene al enviar menos paquetes debe equilibrarse con los siguientes costos:
- Uso de memoria: Los búferes más grandes requieren más memoria asignada al dispositivo de red para la recepción de paquetes. Si tienes muchas colas, es posible que una cantidad considerable de memoria quede sin usar (aislada).
- Manejo de paquetes pequeños: Los búferes más grandes manejan los paquetes pequeños, como los acuses de recibo (ACK) puros, con menos eficiencia.
- Costos de asignación de CPU: Los costos de la ruta de datos se ven afectados significativamente por la asignación y liberación de memoria. Alinear el tamaño del paquete con un múltiplo de páginas de memoria ayuda a optimizar este costo de CPU.
- Interacción de TSO: El tamaño del paquete afecta de forma sutil la descarga de segmentación de TCP (TSO). Para crear el paquete de TSO más grande posible, es posible que debas elegir un tamaño máximo de segmento (MSS) más pequeño. Por ejemplo, dado el paquete IP más grande posible de 64 KB, incluidos los encabezados, un MSS de 4 KB genera una carga útil más grande (60 KB) que un MSS de 8 KB (56 KB).
Para la mayoría de las cargas de trabajo, la diferencia en la eficiencia entre las MTU de 4 KB, 8 KB o 9 KB es pequeña. Sin embargo, cualquiera de estos valores representa una mejora significativa en comparación con los paquetes predeterminados de 1,460 bytes.
Recomendación para paquetes del tamaño de la página
Como opción sólida y, en general, eficiente, te recomendamos que establezcas el tamaño de la MTU de tu red de VPC en 4,082 bytes. Se recomienda este tamaño porque permite que todo el paquete Ethernet quepa en una página de memoria de 4,096 bytes, lo que optimiza la asignación de páginas de memoria. Esta recomendación es para la MTU de capa 3, que incluye el encabezado IP, pero excluye la capa de vínculo Ethernet de 14 bytes.
Configuración de MTU de IP
Puedes configurar la MTU para cada red de VPC directamente a través de la consola de Google Cloud .
En la mayoría de las distribuciones de Linux en Google Cloud, no se necesita configuración manual en la instancia de procesamiento. La instancia aprende automáticamente la MTU de la red con DHCP durante el inicio (con la opción 26). Luego, la instancia establece la MTU del dispositivo de red para que coincida. Te recomendamos que uses esta configuración automática.
Si es necesaria la configuración manual, la MTU del dispositivo de red se puede establecer en un valor inferior a la MTU de la red de VPC con el siguiente comando:
ip link set dev $DEV mtu 4082
Cómo establecer diferentes tamaños de MTU para rutas específicas
Si tu instancia de procesamiento se comunica de forma externa fuera de la VPC, donde la MTU de la ruta podría ser más baja, entonces establecer la MTU en rutas específicas es la opción preferida. En esta situación, establece la MTU predeterminada en el valor conservador de 1,460 bytes y aplica la MTU más alta, por ejemplo, 4,082 bytes, solo para las rutas intra-VPC:
#Set intra-VPC route MTU:
ip -4 route change $SUBNET/$MASK dev $DEV mtu 4082
#Set default route MTU:
ip -4 route change default dev $DEV mtu 1460
Configura el tamaño máximo de segmento (MSS) de TCP
El tamaño máximo de segmento (MSS) de TCP determina el tamaño de la carga útil del paquete para una conexión TCP. Dado que los paquetes TCP/IP no deben exceder el tamaño de la MTU para evitar la fragmentación o la pérdida de paquetes, el MSS debe ajustarse en consecuencia.
En general, no es necesario configurar el MSS de TCP de forma manual, ya que el sistema operativo lo deriva automáticamente de la MTU de la ruta.
El MSS abarca la carga útil y las opciones de TCP, pero excluye el encabezado IPv4 de 20 bytes y el encabezado TCP de 20 bytes. Por lo tanto, en una red IPv4, el MSS suele ser 40 bytes más pequeño que la MTU.
Si prefieres un MSS más pequeño para el tráfico específico, puedes configurarlo por ruta. Por ejemplo, si la MTU de tu red de VPC y de tu dispositivo usan el máximo (8,896 bytes) para el tráfico general, pero deseas usar una MTU de 4 KB para el tráfico TCP, puedes usar el siguiente comando:
ip -4 route change default dev $DEV advmss 4042
Modo de división del encabezado
Las plataformas de tercera generación ofrecen una función opcional de división del encabezado de recepción, que está inhabilitada de forma predeterminada.
La división de encabezado separa los encabezados y los datos de los paquetes en búferes distintos. Esto permite completar una página de memoria entera con 4,096 bytes de datos. Esta separación permite optimizaciones cruciales, como reemplazar las costosas operaciones de copia del kernel al espacio del usuario por operaciones de asignación de páginas de memoria más económicas (por ejemplo, con TCP_ZEROCOPY_RECEIVE de Linux).
Cuando se habilita la función de división del encabezado de recepción, cambia el cálculo de la MTU. La MTU óptima es aquella en la que todos los encabezados se asignan al búfer de encabezado y el búfer de carga útil llena una página completa de datos. Con la división de encabezado habilitada:
- Un búfer de encabezado contiene lo siguiente:
- Ethernet (14 bytes)
- IPv4 (20 bytes)
- Encabezados TCP (20 bytes)
- Opciones comunes de TCP (12 bytes para la configuración predeterminada con marcas de tiempo de TCP)
- El búfer de datos contiene 4,096 bytes de datos de carga útil.
Esto da como resultado un tamaño total de fotograma de 4,162 bytes y, por lo tanto, una MTU de 4,148 bytes.
¿Qué sigue?
- Lee la entrada de blog sobre los 5 pasos para mejorar el rendimiento de las redes. Google Cloud
- Obtén información sobre los Productos de Herramientas de redes globales.
- Obtén más información sobre los Niveles de Herramientas de redes en Google Cloud.
- Aprende a comparar el rendimiento de la red.