...

Cómo configurar correctamente el equilibrio de IRQ en Linux: guía práctica

En Linux, IRQ Balance controla la distribución de las interrupciones de hardware entre los núcleos de la CPU y, por lo tanto, determina si la carga de red se distribuye de forma uniforme o si algunos núcleos se ven ralentizados. Te voy a enseñar cómo utilizar irqbalance de forma específica, cuándo cambiar a la afinidad de IRQ manual y qué ajustes se deben aplicar en servidores con alta carga de red lo que realmente importa.

Puntos centrales

Antes de entrar en detalles, voy a resumir las decisiones más importantes que me han ayudado de forma fiable en proyectos con una elevada carga de E/S. Considero que la distribución automática mediante irqbalance es un buen punto de partida; mido el efecto y realizo ajustes selectivos. En el caso de cargas de trabajo deterministas, asigno manualmente IRQ concretas a núcleos específicos y excluyo el resto de CPU de la distribución automática. Tengo en cuenta la proximidad NUMA desde el principio, ya que reduce la latencia y garantiza el rendimiento. Gracias a una supervisión clara, detecto los cuellos de botella más rápidamente y los regulo sin innecesarias Riesgos.

Esta lista te muestra a qué presto especial atención a la hora de realizar la configuración:

  • Automático En primer lugar: activar irqbalance y medir su efecto
  • afinidad De forma específica: fijar las IRQ críticas, reducir el jitter
  • CPU prohibidas: Mantener núcleos libres para los hilos de las aplicaciones
  • NUMA Tenga en cuenta lo siguiente: mantenga las IRQ cerca del nodo de memoria
  • Monitoreo: Comprobar /proc/interrupts y las latencias

Conceptos básicos sobre las IRQ explicados brevemente

Una solicitud de interrupción (IRQ) es una señal mediante la cual el hardware transfiere trabajo a la CPU, interrumpiendo así una tarea en curso. Si llegan demasiadas de estas señales al mismo núcleo, la carga de trabajo en él aumenta y el tiempo de respuesta se vuelve lento, mientras que otros núcleos permanecen sin utilizarse; eso es precisamente lo que quiero conseguir con Distribución evitar. irqbalance distribuye estas IRQ de forma dinámica entre varios núcleos y evalúa periódicamente el estado del sistema. Para ello, lo primero que hago es consultar /proc/interrupciones y comprueba en las columnas cuántas IRQ llegan por cada CPU. Si alguna columna se desborda, la regulo activamente y así reduzco las Puntos de acceso.

Distribución automática con irqbalance

En las distribuciones modernas, empiezo con el servicio irqbalance, que, por defecto, ajusta periódicamente la distribución de las IRQ. Lo activo con systemctl enable --now irqbalance y compruebo el estado antes de intervenir más a fondo; así aprovecho lo que ya hay Automático. Los archivos de configuración se encuentran, según el sistema, en /etc/sysconfig/irqbalance o /etc/default/irqbalance, allí puedo descartar CPU o IRQ. La variable resulta especialmente útil IRQBALANCE_BANNED_CPUS como máscara de 64 bits para reservar núcleos específicos para las aplicaciones. Quien desee profundizar en ejemplos prácticos, encontrará aquí una introducción concisa a la Rendimiento de la red, a las que suelo hacer referencia en los talleres y que aplico en los proyectos.

Cómo configurar de forma segura la afinidad de IRQ de forma manual

Cuando las cargas de trabajo son muy sensibles a la fluctuación o cuando se quiere que determinados núcleos permanezcan libres exclusivamente para procesos del espacio de usuario, configuro manualmente la afinidad de IRQ. Para ello, escribo máscaras de bits según /proc/irq/NÚMERO DE IRQ/smp_affinity y establezco en qué núcleos se puede ejecutar una interrupción; esto permite planificar Conducta. En primer lugar, determino los números de IRQ relevantes con grep en /proc/interrupciones. En el caso de los dispositivos de red, suelo asignar las colas RX/TX a núcleos cercanos a los hilos de la aplicación, mientras que mantengo libres otros núcleos. En este breve artículo se resumen bien los fundamentos de este procedimiento Guía de afinidad de IRQ, que utilizo habitualmente como punto de partida.

La siguiente tabla muestra las máscaras de bits más habituales y su significado. Utilizo estos ejemplos para establecer configuraciones de forma rápida y con pocos errores, y comprobar después el resultado con /proc/interrupciones a verificar.

Objetivo Máscara de ejemplo (hex) núcleos Comentario
Solo CPU0 0x1 0 Prueba sencilla, bajo dispersión
Solo CPU1 0x2 1 Separa las IRQ de la CPU0, reduce Interferencia
CPU0–CPU1 0x3 0-1 Distribuido entre dos núcleos, ligero Ayuda
CPU2–CPU3 0xC 2-3 Útil cuando 0–1 para los hilos de aplicaciones gratis permanezca en
CPU0–CPU3 0xF 0–3 Distribución amplia en 4 núcleos, mezcla Carga

Medición: leer correctamente /proc/interrupts

Abro el archivo /proc/interrupciones y veo una IRQ por fila y, por columna, los contadores de cada CPU; eso hace que se aprecien inmediatamente los desequilibrios visible. Si una columna crece mucho más rápido que las demás, la carga se concentra allí. Entonces compruebo qué controlador está implicado y si RSS/RPS ya la ha distribuido. Además, ejecuto irqbalance temporalmente en primer plano con salida de depuración, para comprender sus decisiones y evitar errores de valoración. Tras cada cambio, vuelvo a comprobar los contadores y mido la latencia bajo carga, para poder corroborar los efectos y descartar Riesgos puede evitar.

Aislamiento de la CPU y máscaras de exclusión

He puesto IRQBALANCE_BANNED_CPUS, para excluir sistemáticamente determinados núcleos de la distribución automática; de este modo, libero recursos para los hilos de las aplicaciones. En configuraciones más recientes, utilizo además IRQBALANCE_BANNED_IRQS, si se quiere que cada dispositivo funcione de forma independiente en un núcleo; esto reduce las interferencias en los sistemas sensibles Cargas de trabajo. En situaciones que requieren baja latencia, desactivo irqbalance de forma específica y asigno las IRQ de manera estática, para que no interfiera ninguna redistribución. Quien quiera comprender con más detalle la asignación de la CPU para la gestión de interrupciones, encontrará información útil sobre el Gestión de interrupciones en los servidores. Lo importante es: primero medir, luego definir y volver a comprobar el efecto, para evitar sorpresas en el Operación que hay que evitar.

Aspectos relacionados con NUMA y proximidad

En los sistemas NUMA, procuro dirigir las IRQ, en la medida de lo posible, a los núcleos de aquel nodo NUMA en cuya memoria se encuentran los datos en cuestión; esto reduce la latencia y aumenta Rendimiento. Lo combino con la afinidad de CPU para la aplicación, de modo que los subprocesos y las interrupciones se ejecuten localmente entre sí. irqbalance funciona bien en NUMA, pero, si es necesario, realizo ajustes con máscaras de exclusión. Es fundamental no distribuir la carga entre nodos si esta puede mantenerse a nivel local. Quien mantenga esta proximidad obtendrá tiempos de respuesta constantes y ahorrará valiosos Cache-Recursos.

Curso intensivo sobre redes: RSS, RPS/RFS y XPS

Antes de ajustar con precisión las máscaras de IRQ, compruebo las características de la tarjeta de red, como RSS, así como los mecanismos del núcleo, como RPS/RFS y XPS; estos influyen en gran medida en la distribución de los paquetes. RSS ya distribuye las interrupciones de cola entre varios núcleos, mientras que RPS/RFS configuran el procesamiento en el núcleo y XPS determina las rutas de transmisión; esto evita innecesarias Puntos de acceso. Ajusto estos mecanismos con mi estrategia de IRQ para que no interfieran entre sí. Si las colas, las afinidades de IRQ y la afinidad de las aplicaciones están bien sincronizadas, la E/S de red funciona mucho mejor. A continuación, vuelvo a realizar mediciones bajo carga real antes de continuar con Pasos pongo.

MSI-X, colas múltiples y una disposición ordenada de las colas

Muchas tarjetas de red de 10 a 100 G utilizan MSI-X y proporcionan vectores de interrupción propios para cada cola de recepción/transmisión. Primero compruebo con ethtool -l eth0 (número de canales) y /proc/interrupciones, cuántas colas están realmente activas y cómo se llaman (por ejemplo,. eth0-TxRx-0, eth0-TxRx-1). El objetivo es ajustar el número de colas al número de núcleos utilizados por nodo NUMA y fijarlas de forma determinista. Con ethtool -L eth0 combined N Configuré el número de colas; a continuación, ordené las IRQ resultantes mediante smp_affinity a los núcleos adecuados. Me aseguro de asignar los pares RX/TX de una misma cola al mismo núcleo o, al menos, al mismo socket, para que Localidad de la caché se aplica. Importante: compruebo los cambios en el número de colas y la afinidad directamente en /proc/interrupciones y con una breve prueba de carga (pps/Throughput), antes de seguir optimizando.

Coalescencia de interrupciones y presupuesto NAPI

Sobre todo cuando hay un gran volumen de paquetes, los valores de coalescencia influyen en la eficacia de mi estrategia de IRQ. Con ethtool -c eth0 veo si rx-usecs y monturas rx están configurados. Una mayor coalescencia reduce el número de IRQ por segundo y ahorra recursos de la CPU, pero aumenta la latencia y la fluctuación. Realizo los ajustes con cuidado: pequeños pasos, midiendo cada vez (latencia p95/p99 y carga de la CPU). En el lado del emisor, se observa tx-usecs de forma analógica. Además, ajusto el comportamiento de NAPI mediante net.core.netdev_budget y net.core.netdev_budget_usecs, cuando NET_RX empieza a acumularse en las SoftIRQ. Si las pérdidas aumentan en /proc/net/softnet_stat, a modo de prueba, aumento el presupuesto o distribuyo las colas RX de forma más sistemática; si la latencia del sistema se vuelve excesiva, lo reduzco. Tengo en cuenta la interacción entre GRO/LRO y TSO/GSO: una agregación excesiva reduce la carga de IRQ, pero puede generar picos de latencia; los compenso con el perfil de la aplicación.

Lectura transparente de SoftIRQs

Además de las HardIRQ, yo decido la carga en las SoftIRQ. Con cat /proc/softirqs Observo NET_RX y NET_TX por CPU; si algunas columnas destacan especialmente, se acumula demasiado trabajo en los subprocesos de ksoftirqd. Un top -H muéstrame rápidamente cuáles ksoftirqd/N Los núcleos suponen una carga. Mido a mayor profundidad con perf top o breves registro perf Ejecutar para detectar puntos críticos en el controlador o en el procesamiento de la pila. Si los hilos de ksoftirqd se activan (en lugar de procesarse directamente en el contexto de la IRQ), la latencia suele aumentar considerablemente; en ese caso, respondo con una mejor distribución de las colas, un mayor presupuesto NAPI o la asignación específica de CPU a los hilos de ksoftirqd afectados mediante taskset -pc. Importante: documento estos ajustes porque tienen un efecto sutil y, en caso de duda, necesito poder revertirlos rápidamente.

Cómo sacar el máximo partido a SMT/Hyper-Threading y la topología

Con SMT activado, comparto un núcleo físico con dos CPU lógicas. Compruebo las relaciones entre procesadores mediante lscpu -e y /sys/devices/system/cpu/cpuX/topology/thread_siblings_list. En el caso de las rutas en las que la latencia es crítica, evito colocar el hilo de la aplicación y la IRQ correspondiente en el mismo núcleo físico (hilos SMT diferentes), ya que compiten por las unidades de ejecución y las cachés. Prefiero pares en los que, por ejemplo, un hilo de aplicación se ejecute en la CPU2 y la cola de recepción (RX) correspondiente en la CPU3 (otro núcleo físico, mismo nodo NUMA). Si la SMT altera la constancia, opto por utilizar menos núcleos físicos, pero exclusivos, y así me ahorro problemas de inestabilidad. Interferencias.

Virtualización: KVM, vhost y SR-IOV

En entornos virtualizados, considero por separado el host y el invitado. En el host, distribuyo de forma ordenada las IRQ de las tarjetas de red físicas entre los núcleos del nodo NUMA correspondiente. Si el invitado utiliza virtio-net, se generan IRQ adicionales para los hilos vhost; las detecto en /proc/interrupciones y asigno de forma coherente los trabajadores de vhost a las colas de la tarjeta de red física. A nivel de máquina virtual, también configuro las afinidades RSS/XPS e IRQ, siempre que el controlador virtio proporcione varias colas. En el caso de SR-IOV, merece la pena asignar a cada invitado una o varias VF con sus propios vectores MSI-X y fijarlas en el invitado; el aislamiento mejora la latencia y la previsibilidad. Sigo un esquema claro: las vCPU del invitado en pCPU dedicadas, las IRQ asociadas en núcleos cercanos, y no mezclar los hilos del emulador y del vhost con los hilos de aplicaciones que requieren un uso intensivo de recursos; de este modo, la ruta de datos planificable.

Frecuencia de la CPU, estados C y ajuste NOHZ

Las latencias de IRQ se ven afectadas cuando los núcleos entran en estados C profundos o se regulan de forma agresiva. Para cargas de trabajo sensibles, configuro el regulador de la CPU en rendimiento (cpupower frequency‑set -g performance) y reduzco los estados C profundos mediante opciones de arranque o de controladores para limitar los tiempos de reactivación. En servidores con una carga elevada, esto suele tener un efecto más positivo que cualquier ajuste fino de las afinidades. En perfiles de latencia muy exigentes, añado nohz_full= y rcu_nocbs= para núcleos aislados, de modo que el tick-timer y las llamadas de retorno de la RCU no interfieran entre sí; defino las CPU de mantenimiento de forma deliberadamente separada. Sin embargo, pruebo estas modificaciones por separado, ya que pueden tener efectos secundarios en la programación y el consumo energético. Lo fundamental sigue siendo: comparar con precisión los valores medidos antes y después del cambio; de lo contrario, me perdería en Optimizaciones en la oscuridad.

Systemd, Cgroups y el aislamiento de aplicaciones

Además de la asignación fija de IRQ, separo los subprocesos de las aplicaciones mediante Cgroups y systemd-affinity. A través de Afinidad CP= En los archivos Unit y los controladores de CPU (cgroup v2), asigno núcleos fijos a los servicios. De este modo, evito que, por parte del programador, los subprocesos se desplacen a aquellas CPU que he destinado a las IRQ. En entornos de contenedores, configuro cpuset.cpus y compruebe cpuset.cpus.effective, para que las promesas de recursos surtan efecto de verdad. Importante: IRQBALANCE_BANNED_CPUS solo controla aquellos casos en los que irqbalance no distribuye; los hilos del núcleo, como ksoftirqd, siguen dependiendo del programador. Por lo tanto, para lograr un aislamiento estricto, necesito una combinación de afinidades de IRQ, afinidad de CPU de los servicios y, si es necesario, núcleos aislados. De este modo, la ruta de datos y la aplicación permanecen claramente separadas y la Carga no se mezcla de forma descontrolada.

Errores habituales y soluciones

Nunca desactivo «irqbalance» de forma generalizada sin conocer los perfiles de carga; de lo contrario, las IRQ se concentran rápidamente en unos pocos núcleos. Igualmente poco recomendable es abrir todos los núcleos para todas las IRQ, aunque los hilos sensibles sean exclusivos Recursos necesitan. Otro error: no probar los cambios de forma aislada y no medir sus efectos; así no queda claro qué es lo que realmente ayuda. También tengo en cuenta los pares de Hyper-Threading: es mejor que el hilo de la aplicación y la IRQ asociada no compartan el mismo núcleo físico. Documento cada paso y creo puntos de restauración para poder volver rápidamente a la última bien Vuelvo a la configuración.

Lista de comprobación práctica para servidores

Siempre empiezo con una configuración inicial: activar irqbalance, registrar la carga del sistema, observar /proc/interrupts y medir las latencias; solo después modifico los ajustes. En el segundo paso, termino con IRQBALANCE_BANNED_CPUS selecciono aquellos núcleos que deben reservarse para los hilos de aplicaciones; de este modo evito interferencias innecesarias de las IRQ. A continuación, conecto las IRQ críticas mediante smp_affinity me centro en unos pocos núcleos bien seleccionados y mantengo la proximidad NUMA. A continuación, compruebo los valores de RSS/RPS/RFS y XPS, así como las opciones de descarga de la NIC, para distribuir el trabajo de forma óptima. Por último, realizo pruebas con carga de producción, comparo las métricas y solo mantengo aquellos cambios que hayan demostrado trabajo.

Archivos de configuración y comandos de systemd

Activo el servicio con systemctl enable --now irqbalance y comprueba con systemctl status irqbalance la duración; así es como lo establezco Servicio seguro que está listo. En /etc/sysconfig/irqbalance o /etc/default/irqbalance pongo IRQBALANCE_BANNED_CPUS así como, opcionalmente, IRQBALANCE_BANNED_IRQS. Aplico los cambios con systemctl restart irqbalance y, al mismo tiempo, observo los contadores en /proc/interrupciones. Para las pruebas, utilizo el modo «Foreground» de irqbalance para seguir las decisiones en tiempo real. Solo cuando comprendo el comportamiento, introduzco los ajustes de forma permanente en el Configuración.

Cuándo desactivo irqbalance

En configuraciones en tiempo real o en aplicaciones extremadamente sensibles a la latencia, detengo «irqbalance» y asigno las IRQ de forma estática para que ninguna redistribución interfiera. Aíslo los núcleos para estas cargas de trabajo y dejo que las IRQ de tráfico se ejecuten deliberadamente en otros núcleos; de este modo, los hilos de las aplicaciones planificable. Este enfoque también resulta útil en entornos de inquilinos estrictamente separados, ya que reduce las interferencias entre máquinas virtuales o contenedores. Si hay controladores que funcionan peor con el modo automático, excluyo sus IRQ mediante una lista de controladores prohibidos. En cuanto los patrones de carga vuelven a ser más variables, vuelvo a activar irqbalance y compruebo el efecto con datos recientes Valores medidos.

Brevemente resumido

Empiezo con irqbalance, mido el efecto y realizo ajustes selectivos, en lugar de intervenir a ciegas en todas partes; así mantengo una visión global del sistema y Transparencia. Para las cargas de trabajo sensibles, asigno las IRQ adecuadas, aíslo los núcleos para las aplicaciones y tengo en cuenta la proximidad NUMA. Mediante máscaras de exclusión, controlo dónde puede actuar irqbalance y evito desplazamientos no deseados. Compruebo periódicamente /proc/interrupciones, latencia y rendimiento, para que los cambios queden debidamente documentados. Quien actúe así aprovechará al máximo el potencial de IRQ Balance y mantendrá los servidores bajo una carga de red notablemente reactivo.

Artículos de actualidad