Parámetros de rendimiento de red en Linux
(github.com/leandromoreira)- Un breve tutorial que muestra dónde se ubican los parámetros de sysctl/red más usados dentro del flujo de red de Linux
- No es realista esperar valores de cargo cult que ofrezcan al mismo tiempo alto rendimiento y baja latencia en todas las situaciones; las versiones modernas del kernel ya traen valores predeterminados bien ajustados y cambiar esos valores puede perjudicar el rendimiento
- La ruta de recepción se organiza como el flujo desde la verificación MAC/FCS del NIC, DMA, ring buffer de recepción, hard IRQ, NAPI, soft IRQ, ingress qdisc, netfilter, máquina de estados TCP, búfer de recepción basado en
tcp_rmem, hasta la lectura de la aplicación - La ruta de transmisión se organiza como el flujo desde
sendmsgde la aplicación, asignación deskb_buff, búfer de escritura del socket basado entcp_wmem, procesamiento de cabeceras TCP/IP, netfilter, output qdisc basado entxqueuelen, transmit ring buffer, DMA, hasta la IRQ de finalización de transmisión del NIC - Los puntos clave de ajuste se relacionan con el manejo de ráfagas, uso de CPU, latencia y observación de drops
- Los
rx,txring buffer son colas para recibir ráfagas de conexiones sin drops, aunque al aumentarlos puede subir la latencia rx-usecs,tx-usecs,rx-frames,tx-framesson el tiempo de espera y la cantidad de frames antes de generar un hard IRQ; permiten reducir el uso de CPU y los hard IRQ, y aumentar el rendimiento a costa de la latencianetdev_budget_usecs,netdev_budget,dev_weight,netdev_max_backlogse relacionan con el NAPI polling cycle y el rendimiento de procesamiento de ingress qdisctxqueuelenydefault_qdiscse relacionan con la cola del lado de OUTPUT y la queuing discipline predeterminada
- Los
- La verificación, cambio y monitoreo se centran en
ethtool,sysctl,ip,tcy archivos de/proc- Ejemplo: consultar el ring buffer con
ethtool -g ethX, cambiarlo conethtool -G ethX rx value tx value - Ejemplo: consultar
net.core.netdev_budget_usecsconsysctl net.core.netdev_budget_usecs, cambiarlo consysctl -w net.core.netdev_budget_usecs value - Ejemplo: consultar
default_qdiscconsysctl net.core.default_qdisc, monitorearlo contc -s qdisc ls dev ethX
- Ejemplo: consultar el ring buffer con
- Los elementos de búfer TCP cubren
tcp_rmem,tcp_wmemytcp_moderate_rcvbuf; cuandotcp_moderate_rcvbufestá configurado, TCP intenta ajustar automáticamente el tamaño del búfer de recepción - Junto con ello se resumen elementos relacionados con el estado TCP y el control de congestión, como
net.core.somaxconn,tcp_fin_timeout,tcp_available_congestion_control,tcp_congestion_control,tcp_max_syn_backlog,tcp_syncookiesytcp_slow_start_after_idle - El rastreo interno de red en Linux puede inspeccionarse con perf, y el comando de ejemplo tiene la forma
perf trace --no-syscalls --event 'net:*' ping globo.com -c1 > /dev/null - Como herramientas de prueba y monitoreo se proponen iperf3, vegeta, netdata, y la combinación de prometheus + grafana + node exporter full dashboard
1 comentarios
Opiniones en Hacker News
En los valores predeterminados de Ubuntu Linux, net.ipv4.tcp_rmem es de unos 6 MB y net.core.rmem_max de alrededor de 1 MB, lo que genera una situación extraña.
Un socket TCP predeterminado, si lo necesita, puede subir la ventana de recepción TCP hasta 6 MB, pero si una app en espacio de usuario llama a
setsockopt SO_RCVBUF, incluso un socket que ya podía usar 6 MB queda limitado a un máximo de 1 MB.Incluso si intentas bajarlo de 6 MB a 4 MB, el resultado termina siendo 1 MB, lo que se ve muy raro; lo mismo aplica a
SO_SNDBUF/wmem.Parece como si Linux confundiera la prioridad de estas opciones, y me pregunto por qué no ponen
core.rmem_maxmás alto y lo toman como el valor directivo autoritativo, o si hay alguna razón histórica.SO_SNDBUF/wmemse puede bajar TCP_NOTSENT_LOWAT.Ese valor limita la cantidad que se bufferiza adicionalmente por encima de lo necesario para el producto ancho de banda-retardo (BDP).
En el momento en que configuras
SO_RCVBUF, ese socket deja de usar el ajuste automático ynet.core.rmem_maxpasa a ser el valor máximo.Está documentado con bastante claridad en
Documentation/networking/ip-sysctl.rst.Es excelente, incluso muestra todos los pasos desde que un paquete entra por la NIC hasta que llega al espacio de usuario.
Para agregar algo más sobre rendimiento de red: si el sistema tiene varios CPU, conviene revisar la asignación NUMA, común en servidores grandes.
Si la tarjeta de red está del lado de un CPU y la aplicación se ejecuta en otro, eso también puede afectar el rendimiento.
Si de verdad quieres aprender sobre transmisión y recepción de red, valen la pena.
https://blog.packagecloud.io/monitoring-tuning-linux-network...
https://blog.packagecloud.io/monitoring-tuning-linux-network...
https://packagecloud.io/blog/illustrated-guide-monitoring-tu...
Solo cambiar el control de congestión predeterminado de Linux,
net.ipv4.tcp_congestion_control, a bbr puede marcar una diferencia enorme en algunas situaciones.Probablemente sobre todo cuando hay distancia, pérdida intermitente de paquetes y jitter, o encapsulación.
Durante el último año estuve depurando un problema en el flujo
client host <-- HTTP --> reverse proxy host <-- HTTP over Wireguard --> service host: en promedio era difícil superar el 20% del rendimiento máximo teórico, y con el tiempo la conexión se volvía tan lenta que casi se detenía.Estuve usando como paliativo cerrar conexiones por la fuerza con frecuencia, pero al cambiar el control de congestión a
bbrobtuve un rendimiento cercano al máximo teórico y conexiones estables; ese cambio fue necesario en ambos extremos de Wireguard.La mayoría de las pilas TCP, al ver la primera pérdida, reducen la ventana de envío a la mitad o la bajan mucho; por eso, si es una VPN con pérdidas o si envías ráfagas grandes a 1 Gb/s hacia un uplink VPN de 10 Mb/s, TCP ve pérdidas y retrocede muchísimo.
BBR intenta encontrar el ancho de banda del cuello de botella: mide el tiempo de ida y vuelta y aumenta la tasa de transmisión hasta que el RTT empieza a subir.
Cuando el RTT aumenta, asume que se está formando una cola en el tramo más estrecho de la ruta, baja la tasa de transmisión hasta que la cola se vacía y el RTT se normaliza, luego envía a esa velocidad durante un rato y vuelve a probar subir un poco.
Hace unos años cambié de un uplink de cable de 10 Mb/s a una fibra simétrica de 1 Gb/s y me molestaba que las subidas por la VPN de la empresa siguieran en torno a 5 Mb/s; al cambiar en FreeBSD a RACK TCP o BBR, subió unas 8 veces hasta el límite de la VPN, alrededor de 40 Mb/s.
El tuning de rendimiento tipo culto cargo-cult, de copiar y pegar un único valor mágico que supuestamente mejora todo, es justo lo contrario de lo que intenta decir el texto original.
Por suerte, Google está subiendo BBRv3 al upstream, así que pronto debería mejorar.
Si solo quieres mejorar el rendimiento en una dirección, no hace falta cambiar ambos extremos de Wireguard.
Sobre BBRv1, coincido con los otros comentarios, y la implementación de cubic del kernel de Linux funciona bastante bien para la mayoría de las aplicaciones.
Me pregunto si el ajuste de rendimiento también tiene sentido para los adaptadores Wi‑Fi.
En escritorio, también me pregunto si hay alguna forma de solucionar los problemas de Ethernet de i210 e i225 que no sea desactivar funciones.
Parece que hoy en día estas dos son las NIC más comunes, y no entiendo bien por qué hardware y drivers de red tan comunes tienen tantos defectos.
Me interesa mucho RISC‑V, pero pienso que tal vez se podría empezar por una NIC completamente abierta y correcta.
Si es más barata que la i210, al final la incluirían, aunque quizá sea algo imposible.
Eso sí, en Wi‑Fi siguen ocurriendo picos aleatorios de ping.
Hay un hilo grande en https://forum.openwrt.org/t/aql-and-the-ath10k-is-lovely/590... sobre activar y ajustar AQM, y sobre el compromiso entre throughput y latencia.
1 Gb no es algo especialmente difícil para CPUs de la misma época, y la i210 ofrece 4 colas.
Me pregunto qué te molesta de la i210.
El resumen gráfico de las colas de red de Linux es excelente, tanto que dan ganas de pegarlo en alguna pared.
El libro Systems Performance de Brendan también cubre bien el rendimiento de red en Linux, entre otros temas, y ya va por la 2.ª edición.
Ambas ediciones son excelentes, pero la 2.ª se centra principalmente en Linux, mientras que la 1.ª también incluye Solaris.
Más recientemente, el mismo autor publicó el libro BPF Performance Tools.
[1] Systems Performance: Enterprise and the Cloud, 2nd Edition (2020)
https://www.brendangregg.com/systems-performance-2nd-edition...
[2] BPF Performance Tools:
https://www.brendangregg.com/bpf-performance-tools-book.html
Disfruté incluso con solo hojear el artículo; la investigación y la estructura están muy bien.
Pero me pregunto quién, en la práctica, ajusta regularmente los parámetros de red de Linux.
Creo que este documento debería indicar explícitamente TCP en algún lugar.
El contenido está muy enfocado en cuestiones relacionadas con TCP y, como la gente usa principalmente TCP, es útil.
Pero los valores de ajuste predeterminados de UDP son pésimamente bajos, y esa parte brilla por su ausencia.
Me gustaría recibir recomendaciones de videos o series que traten temas similares.
Hay mucho material general sobre redes, pero me resultó difícil encontrar recursos que aborden la implementación específica de Linux.
Quiero crear un servidor TCP echo sencillo para microcontroladores, pero la mayoría de los ejemplos solo usan la biblioteca TCP propia del proveedor y casi no explican el proceso de configurar y establecer una conexión directa con el router.