4 puntos por GN⁺ 2023-09-07 | 1 comentarios | Compartir por WhatsApp
  • 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 sendmsg de la aplicación, asignación de skb_buff, búfer de escritura del socket basado en tcp_wmem, procesamiento de cabeceras TCP/IP, netfilter, output qdisc basado en txqueuelen, 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, tx ring 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-frames son 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 latencia
    • netdev_budget_usecs, netdev_budget, dev_weight, netdev_max_backlog se relacionan con el NAPI polling cycle y el rendimiento de procesamiento de ingress qdisc
    • txqueuelen y default_qdisc se relacionan con la cola del lado de OUTPUT y la queuing discipline predeterminada
  • La verificación, cambio y monitoreo se centran en ethtool, sysctl, ip, tc y archivos de /proc
    • Ejemplo: consultar el ring buffer con ethtool -g ethX, cambiarlo con ethtool -G ethX rx value tx value
    • Ejemplo: consultar net.core.netdev_budget_usecs con sysctl net.core.netdev_budget_usecs, cambiarlo con sysctl -w net.core.netdev_budget_usecs value
    • Ejemplo: consultar default_qdisc con sysctl net.core.default_qdisc, monitorearlo con tc -s qdisc ls dev ethX
  • Los elementos de búfer TCP cubren tcp_rmem, tcp_wmem y tcp_moderate_rcvbuf; cuando tcp_moderate_rcvbuf está 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_syncookies y tcp_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

 
GN⁺ 2023-09-07
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_max más alto y lo toman como el valor directivo autoritativo, o si hay alguna razón histórica.

    • Si lo que se busca es limitar la cantidad de datos con buffering excesivo, en lugar de SO_SNDBUF/wmem se 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).
    • El valor máximo de net.ipv4.tcp_rmem es el límite del ajuste automático que realiza el kernel.
      En el momento en que configuras SO_RCVBUF, ese socket deja de usar el ajuste automático y net.core.rmem_max pasa 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.

  • 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 bbr obtuve un rendimiento cercano al máximo teórico y conexiones estables; ese cambio fue necesario en ambos extremos de Wireguard.

    • BBR es distinto porque no usa la pérdida como señal de congestión.
      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.
    • BBRv1 está roto, así que no debería usarse en Internet público.
      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.
    • El control de congestión funciona desde el lado que envía datos hacia el lado que los recibe.
      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.

    • Si puedes sacrificar entre 10 y 20% del throughput máximo de la red local, puedes aumentar mucho la equidad en Wi‑Fi, mejorar los tiempos de ping y reducir el bufferbloat.
      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.
    • La i225 simplemente está rota, pero la i210 ofrece un rendimiento excelente.
      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.
    • Usaba una motherboard con i225 onboard y resolví el problema comprando una PCIe I350.
  • 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 pregunto si hay buenos recursos para el ajuste de UDP.
  • 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.

    • También necesito el mismo tipo de material desde la perspectiva de los microcontroladores.
      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.