...

Équilibrage IRQ des serveurs et performances réseau pour l'hébergement à forte charge

Une charge réseau élevée se décide par le traitement efficace de IRQ du serveur des signaux : En répartissant intelligemment les interruptions sur les cœurs du CPU, on réduit la latence et on évite les drops. Dans ce guide, je montre de manière pratique comment combiner IRQ-Balancing, RSS/RPS et CPU-Affinity afin d'assurer durablement un hébergement à forte charge. performant d'exploiter.

Points centraux

  • Distribution de l'IRQ évite les points chauds sur les différents cœurs de l'unité centrale.
  • Multi-queues plus RSS/RPS parallélise le traitement des paquets.
  • Attention NUMA réduit les accès cross-node et la latence.
  • Gouverneur de l'unité centrale et le thread pinning lissent les temps de réaction.
  • Suivi Vérifie les pps, les latences, les drops et l'utilisation du noyau.

Les IRQ expliqués en bref : pourquoi ils contrôlent la charge du réseau

Pour chaque paquet entrant, la carte réseau signale par IRQ, que du travail est en cours, sinon le noyau devrait polluer activement. Si l'allocation reste sur un noyau, sa charge de travail augmente, alors que les autres noyaux inutilisé restent en place. C'est à ce moment précis que les latences augmentent, que les tampons d'anneau RX se remplissent et que les pilotes commencent à rejeter des paquets. Je répartis les interruptions sur les noyaux appropriés pour que le traitement des paquets reste régulier et prévisible. Cela me permet de désengorger les goulots d'étranglement, de lisser les temps de réponse et de maintenir les pertes de paquets dans des limites étroites.

Équilibrage IRQ et affinité CPU sous Linux

Le service irqbalance distribue les interruptions de manière dynamique, analyse la charge et déplace automatiquement les affinités dans le temps. Pour les profils de charge extrêmes, je définis manuellement les affinités via /proc/irq//smp_affinity et lie les files d'attente de manière ciblée à des noyaux de la même NUMA-Nodes. Cette combinaison d'automatisme et de réglage fin m'aide à traiter proprement aussi bien la charge de base que les pics. Pour une approche plus approfondie de Gestion des interruptions et optimisation du CPU comme aide à la réflexion pour la planification. Ce qui reste important : Je relie systématiquement la topologie du matériel, la répartition des IRQ et les fils d'application.

Utiliser les NIC multi-files, RSS et RPS de manière pratique

Les NIC modernes fournissent plusieurs files d'attente RX/TX, chaque file d'attente déclenche ses propres IRQs, et Receive Side Scaling (RSS) répartit les flux sur les noyaux. S'il n'y a pas assez de files d'attente matérielles, j'ajoute dans le noyau Receive Packet Steering (RPS) et Transmit Packet Steering (XPS) pour des flux supplémentaires. Parallélisme. Avec ethtool -L ethX combined N j'adapte le nombre de files d'attente au nombre de noyaux du nœud NUMA correspondant. Je vérifie avec ethtool -S et nstat, si des drops, des busy polls ou des pics de pps élevés se produisent. Pour un lissage plus fin de la charge, j'utilise aussi des Coalescence d'interruption dans la planification, afin que la carte réseau ne génère pas trop d'IRQ individuelles.

Le tableau suivant montre les éléments centraux et les commandes typiques que j'utilise pour une configuration cohérente :

Module Objectif Exemple Remarque
irqbalance Distribution automatique systemctl enable --now irqbalance Point de départ pour les charges de travail mixtes
Affinity Correction de l'épinglage echo mask > /proc/irq/XX/smp_affinity Respecter l'attribution de la NUMA
Queues de billard Plus de parallélisme ethtool -L ethX combined N Matcher sur les noyaux des nœuds
RSS/RPS Répartition des flux sysfs : rps_cpus/rps_flow_cnt Utile si peu de files d'attente NIC
XPS Noyaux de chemins TX ordonnés sysfs : xps_cpus Évite le cache-thrash

Utiliser l'équilibrage automatique des IRQ à bon escient

Pour les serveurs d'hébergement mixtes, l'activation de irqbalance, car le démon détecte en permanence les déplacements de charge. Je vérifie l'état via systemctl status irqbalance et jette un coup d'œil sur /proc/interrupts, pour voir la répartition par file d'attente et par noyau. Si les latences augmentent en pics, je détermine à titre de test les noyaux qui traitent les interruptions en priorité et je compare les valeurs mesurées avant et après la modification. Ce faisant, je conserve la configuration simplement, Ainsi, les audits et les retours en arrière ultérieurs sont rapides. Ce n'est que lorsque les modèles sont clairs que je me lance dans l'épinglage.

Affinité CPU manuelle pour un contrôle maximal

Pour les taux de pps très élevés, j'épingle des queues RX à des noyaux sélectionnés du même NUMA-Je sépare délibérément les threads d'application de ces nœuds. J'isole les différents cœurs pour les interruptions, j'exécute les workers sur les cœurs voisins et je veille strictement à la localité du cache. Je réduis ainsi les accès inter-nœuds et minimise les changements de contexte coûteux dans le chemin chaud. Pour obtenir des résultats reproductibles, je documente clairement les masques IRQ, l'affectation à la file d'attente et l'affinité de thread des services. Cette clarté maintient les temps d'exécution des paquets constant et réduit les fugues.

Optimiser le CPU et les applications de manière propre

Je mets le Gouverneur de l'unité centrale souvent sur „performance“, car les changements d'horloge augmentent les sauts de latence. Je lie les processus critiques comme Nginx, HAProxy ou les bases de données à des noyaux proches des noyaux IRQ, ou je les sépare délibérément si le profil de cache l'exige. Il reste important de limiter les changements de contexte et de maintenir le noyau à jour pour que les optimisations de la pile réseau soient efficaces. Je mesure les effets de chaque changement au lieu de faire des suppositions, et je m'adapte pas à pas. Il en résulte une configuration qui, sous charge prévisible réagit.

Mettre en place correctement le monitoring et la mesure

Sans valeurs mesurées, le réglage reste un jeu de devinettes, c'est pourquoi je commence par sar, mpstat, vmstat, nstat, ss et ethtool -S. Pour les tests de charge structurés, j'utilise iperf3 et je regarde le débit, mais aussi et surtout les pps, la latence, les retransmissions et la charge de base. J'enregistre les tendances à long terme à l'aide de systèmes de surveillance courants afin d'identifier des modèles tels que les pics du soir, les fenêtres de sauvegarde ou les campagnes. Celui qui veut comprendre le chemin des données dans sa globalité profite d'une vue Pipeline de traitement des paquets de l'IRQ du NIC jusqu'à l'espace utilisateur. Seule la combinaison de ces signaux montre si l'équilibrage de l'IRQ et l'affinité donnent les résultats souhaités. Effet apporter.

Comprendre NAPI, Softirqs et ksoftirqd

Pour maîtriser les pics de latence en cas de charge pps élevée, je tiens compte de la NAPI-La mécanique de NAPI et l'interaction entre les Hardirqs et les Softirqs. Après la première IRQ matérielle, NAPI récupère plusieurs paquets dans la file d'attente RX en mode poll afin d'éviter les tempêtes d'IRQ. Si les Softirqs ne sont pas traitées rapidement, elles vont dans ksoftirqd/N Les threads qui ne s'exécutent qu'avec une priorité normale - une raison classique de l'augmentation des latences de queue. J'observe /proc/softirqs et /proc/net/softnet_stat; un haut „time_squeeze“ou drops indiquent un budget trop serré. Avec sysctl -w net.core.netdev_budget_usecs=8000 et sysctl -w net.core.netdev_budget=600 j'augmente à titre d'essai le temps de traitement par NIC-Poll et le budget des paquets. Important : j'augmente les valeurs progressivement, je mesure et je vérifie s'il y a une gigue du processeur ou des interférences avec les threads d'application.

Ajuster avec précision le hachage RSS et la table d'indirection

RSS distribue les flux sur les files d'attente via la table d'indirection (RETA). Je vérifie la clé de hachage et la table avec ethtool -n ethX rx-flow-hash tcp4 et règle la distribution de manière symétrique si nécessaire. Avec ethtool -X ethX equal N ou de manière ciblée par entrée (ethtool -X ethX hkey ... hfunc toeplitz indir 0:1 1:3 ...), j'adapte les affectations aux noyaux préférés d'un nœud NUMA. L'objectif est Flow-StickinessUn flux reste sur le même noyau pour que la localité du cache et la contention de verrouillage dans la pile restent minimales. Pour les environnements avec beaucoup de flux UDP courts, j'augmente rps_flow_cnt par file d'attente RX pour que la distribution logicielle ait suffisamment de buckets et ne crée pas de hotspots. Je garde à l'esprit que les hachages symétriques aident dans les topologies ECMP, mais que dans le contexte du serveur, c'est surtout l'équilibre du noyau qui compte.

Choisir judicieusement les offloads, les GRO/LRO et les tailles d'anneau

Les charges utiles matérielles soulagent le CPU, mais peuvent modifier les profils de latence. Je vérifie avec ethtool -k ethX, si TSO/GSO/UDP_SEG sur TX et GRO/LRO sont actifs sur RX. GRO regroupe les paquets dans le noyau et est presque toujours utile pour le débit ; LRO peut être problématique dans les configurations de routage ou de filtrage et il vaut mieux s'en abstenir. Pour les APIs critiques en termes de latence, je teste une agrégation GRO plus petite (ou temporairement désactivée) lorsque les latences p99 dominent. De même, j'ajuste les tailles d'anneau via ethtool -G ethX rx 1024 tx 1024Les anneaux plus grands interceptent les bursts mais augmentent la latence dans la congestion ; les anneaux trop petits provoquent des rx_missed_errors. Je me base sur les mesures de ethtool -S (par exemple. rx_no_buffer_count, rx_dropped) et je l'accorde avec BQL (Byte Queue Limits, automatique côté noyau), afin que les queues TX ne soient pas suralimentées.

Virtualisation : IRQ dans les VM et sur l'hyperviseur

Dans les configurations virtualisées, je contrôle la répartition physique des cartes d'interface réseau sur l'hôte et j'y définis les paramètres suivants Équilibrage de l'IRQ clairement sur . Les VM reçoivent suffisamment de vCPU, mais j'évite le surcommitment aveugle pour que les retards d'ordonnancement n'augmentent pas la latence. Les pilotes paravirtualisés modernes comme virtio-net ou vmxnet3 me fournissent les meilleurs chemins pour des taux pps élevés. Au sein de la VM, je vérifie à nouveau l'affinité et le nombre de files d'attente afin que l'invité ne devienne pas un goulot d'étranglement. Il est essentiel d'avoir une vue d'ensemble de l'hôte et de l'invité afin que l'ensemble du chemin de données c'est vrai.

Approfondir la virtualisation : SR-IOV, vhost et OVS

Pour des taux de pps très élevés, j'utilise sur l'hyperviseur SR-IOVJe lie les fonctions virtuelles (VF) de la carte réseau physique directement aux machines virtuelles et les épingle aux noyaux du nœud NUMA correspondant. Cela permet de contourner une partie de la pile d'hôtes et de réduire la latence. Lorsque le SR-IOV ne convient pas, je fais attention aux points suivants vhost-net et j'épingle les threads vhost comme les workers d'application et les noyaux IRQ, afin d'éviter les sauts cross-NUMA. Dans les configurations d'overlay ou de commutation, j'évalue les coûts supplémentaires engendrés par Linux-Bridge ou OVS ; pour les profils extrêmes, je ne place OVS-DPDK que si l'effort opérationnel justifie l'avantage mesurable. Là encore, je mesure les pps, la latence et la répartition du CPU avant de prendre des décisions, pas après.

Busy Polling et réglage de l'espace utilisateur

Pour les services critiques en termes de latence, on peut Polling busy réduire la gigue. J'active à titre d'essai sysctl -w net.core.busy_read=50 et net.core.busy_poll=50 (microsecondes) et définir par l'option de socket SO_BUSY_POLL de manière sélective pour les sockets concernés. L'espace utilisateur pollue alors juste avant le blocage et attrape les paquets avant qu'ils n'aillent plus loin dans les files d'attente. Cela coûte du temps de CPU, mais donne souvent des latences p99 plus stables. Je maintiens les valeurs faibles, j'observe la charge du noyau et je ne combine le busy polling qu'avec une affinité de thread claire et un gouverneur de CPU fixe, sinon les effets s'annulent mutuellement.

Filtre de paquets, Conntrack et coûts eBPF en vue

Le firewalling et le NAT font partie du chemin de données. Je vérifie donc les nftables/iptables-et je nettoie les règles mortes ou les chaînes profondes. Dans les configurations très fréquentées, j'adapte la taille des tables Conntrack (nf_conntrack_max, ) ou désactiver Conntrack de manière ciblée pour les flux sans état. Si des programmes eBPF (XDP, tc-BPF) sont utilisés, je mesure leurs coûts d'exécution par hook et donne la priorité aux „early drop/redirect“ afin de décharger les chemins coûteux. Il est important de définir clairement les responsabilités : soit l'optimisation intervient dans le NIC-Offload, soit dans le programme eBPF, soit dans la pile classique - un double travail ne fait qu'augmenter la latence.

Isolation du CPU et noyaux de housekeeping

Pour une latence absolument déterministe, je place les travaux de fond sur UC de ménage est désactivé. Les paramètres du noyau comme nohz_full=, rcu_nocbs= et irqaffinity= aident à garder les noyaux dédiés largement libres de la gestion des ticks, des appels RCU et des IRQs étrangers. J'isole un ensemble de cœurs pour les travailleurs d'application et un autre pour les IRQ et les softirqs ; les services système et les temporisateurs fonctionnent sur des cœurs séparés. Cela permet d'avoir des profils de cache propres et de réduire les effets de préemption. L'hyper-threading peut dans certains cas renforcer la gigue ; je teste si la désactivation par paire de cœurs lisse les latences p99 avant de prendre une décision globale.

Playbook de diagnostic et anti-patterns typiques

Lorsque des drops ou des pics de latence apparaissent, je procède de manière structurée : 1) /proc/interrupts vérifier si la répartition n'est pas inégale. 2) ethtool -S sur les drops RX/TX, les erreurs FIFO, rx_no_buffer_count vérifier. 3) /proc/net/softnet_stat après „time_squeeze" ou "drops“. 4) mpstat -P ALL et top pour l'activité de ksoftirqd. 5) Métriques d'application (nombre de connexions actives, retransmissions avec ss -ti). Anti-patterns que j'évite : anneaux RX globalement énormes (cache la congestion), activation/désactivation sauvage des offloads sans mesure, mélange d'affinités fixes avec irqbalance agressive, ou RPS et RSS en même temps sans architecture cible claire. Chaque modification reçoit une comparaison mesure-avant-après et un bref protocole.

Exemples de concepts d'hébergement web et d'APIs

Serveur d'hébergement web classique

Pour de nombreux petits sites, j'active irqbalance, Je règle plusieurs files d'attente et sélectionne le gouverneur de performance. Je mesure les latences L7 pendant les pics et je fais attention aux pics pps, qui se produisent surtout avec TLS et HTTP/2. Si les files d'attente matérielles ne suffisent pas, j'ajoute le RPS pour une distribution supplémentaire au niveau logiciel. Cet ajustement permet de maintenir les temps de réponse constant, même si la charge de travail globale semble modérée. Des contrôles réguliers de /proc/interrupts m'indiquent si des noyaux individuels basculent.

Proxy inverse à forte charge ou passerelle API

Pour les frontaux avec un grand nombre de connexions, j'épingle finement les queues RX sur des noyaux définis et je positionne les proxy workers sur des noyaux proches. Je décide consciemment si irqbalance doit rester actif ou si l'épinglage fixe donne des résultats plus clairs. S'il n'y a pas assez de files d'attente, je choisis RPS/XPS et j'étalonne Coalescence, pour éviter les tempêtes d'IRQ. J'obtiens ainsi une faible latence avec un taux de pps très élevé et je maîtrise les latences de queue. La documentation de chaque modification facilite les audits ultérieurs et maintient le comportement. prévisible.

Choix du fournisseur et critères matériels

Je fais attention aux cartes réseau avec Multi-queues, La latence du backbone est fiable et le noyau de la plateforme est à jour. Une topologie de CPU équilibrée et une séparation NUMA claire empêchent les interruptions de réseau d'atteindre des zones de mémoire éloignées. Pour les projets avec des taux de pps élevés, le choix de l'infrastructure récompense chaque heure de réglage, car le matériel fournit des réserves. Lors de comparaisons pratiques, j'ai bien travaillé avec des fournisseurs qui publient des profils de performance et proposent des paramètres par défaut favorables à l'IRQ, par exemple des fournisseurs comme webhoster.de. De telles configurations me permettent d'utiliser efficacement l'IRQ-Balancing, RSS et Affinity et de réduire les temps de réaction. étroit de tenir.

Procédure pas à pas pour le tuning personnel

Étape 1 : Je détermine l'état actuel avec iperf3, sar, mpstat, nstat et ethtool -S, J'ai donc besoin d'un outil qui me permette d'avoir des valeurs de départ claires. Étape 2 : Si irqbalance ne fonctionne pas, j'active le service, j'attends sous charge et je compare la latence, les pps et les drops. Étape 3 : J'adapte le nombre de files d'attente et la configuration RSS aux noyaux du nœud NUMA correspondant. Étape 4 : Je règle le gouverneur du CPU sur „performance“ et j'affecte les services centraux aux cœurs correspondants. Étape 5 : Ce n'est qu'ensuite que je peaufine l'affinité manuelle et l'épinglage NUMA, dans la mesure où les valeurs de mesure indiquent encore des zones d'étranglement. Étape 6 : Au fil des jours, je vérifie les tendances afin de classer avec certitude les pics d'événements, les sauvegardes ou les pics de marketing.

En bref

efficace Équilibrage de l'IRQ distribue le travail réseau sur les cœurs appropriés, atténue les latences et empêche les drops à un taux pps élevé. En combinaison avec des NIC multi-queues, RSS/RPS, un gouverneur CPU approprié et une affinité de thread propre, j'exploite la pile réseau de manière fiable. Valeurs mesurées à partir de ethtool -S, nstat, sar et iperf3 me guident pas à pas vers mon objectif au lieu de me laisser dans le noir. Celui qui réfléchit à la topologie NUMA, à l'épinglage de l'IRQ et au placement de l'application maintient les temps de réponse faible - même lors des pics de charge. Ainsi, l'hébergement à forte charge reste sensiblement réactif, sans brûler inutilement les réserves de l'unité centrale.

Derniers articles