...

Gestion des interruptions sur les serveurs : comment les interruptions du CPU influencent les performances

Les interruptions CPU contrôlent la vitesse à laquelle mon serveur réagit aux paquets réseau, aux événements de stockage et aux temporisateurs - des interruptions mal réparties ou trop fréquentes ralentissent les applications de manière mesurable. Un serveur de gestion des interruptions propre réduit les changements de contexte, diminue les latences et stabilise les temps de réponse lors des pics de charge.

Points centraux

Je résume de manière compacte les aspects clés suivants avant d'entrer dans les détails :

  • Charge d'interruption comprendre : A partir de quand les pourcentages deviennent critiques
  • Parallélisme gérer les interruptions simultanées et les pires cas de latence
  • MSI-X utiliser les informations : Plus de messages, meilleure distribution
  • RSS & Affinité : placer les interruptions NIC sur les noyaux
  • Suivi s'établissent : Lire les chiffres, agir de manière ciblée

Ce que les interruptions du CPU déclenchent sur les serveurs

Une interruption est un Signal, qui arrache immédiatement le CPU à sa tâche actuelle et lance un gestionnaire. Les cartes réseau signalent les nouveaux paquets, les contrôleurs de stockage signalent les E/S terminées, les temporisateurs déclenchent les horloges - chacune de ces interruptions coûte cher. temps CPU. En cas d'activité élevée, ces événements s'accumulent et entraînent de nombreux changements de contexte et des échecs de cache. C'est pourquoi j'observe à quelle fréquence et pendant combien de temps le CPU du noyau passe des ISR et des DPC. Comprendre cette dynamique permet de gérer les temps de réaction de manière fiable et de maintenir des applications sensiblement plus fluides.

Pourquoi des temps d'interruption élevés coûtent-ils en performance ?

Dans les environnements sains, les interruptions du système se situent généralement entre 0,1-2% CPU, 3-7% sont possibles à court terme. Si le temps d'interruption reste régulièrement supérieur à 5-10%, il s'agit souvent d'un problème de pilote, de matériel défectueux ou d'un mauvais réglage. A partir de 30%, les choses deviennent sérieuses, au-delà de 50%, les risques suivants se présentent Goulots d'étranglement et des temps de réponse difficiles. Les applications perdent du débit, les latences sautent et la prévisibilité en souffre. Je vérifie alors d'abord les niveaux des pilotes, le firmware, les affinités et la modération des interruptions sur les cartes réseau.

Interruptions simultanées : comprendre les latences

Une seule interruption reste rarement un Problème; La situation devient difficile lorsque plusieurs événements entrent en collision. Si une interruption de haute priorité arrive pendant une interruption de basse priorité, le traitement de cette dernière est prolongé par de nouvelles interruptions. Exemple : si le chemin à haute priorité nécessite 75 cycles et le chemin à faible priorité 50, la latence du chemin à faible priorité augmente facilement jusqu'à 125 cycles - d'autres chevauchements font augmenter la latence. Pire cas de figure-latence augmente rapidement. Ce comportement rend les systèmes imprévisibles. C'est pourquoi je planifie les affinités principales et les priorités de manière à ce que les hotpaths ne se bloquent pas mutuellement.

MSI et MSI-X au quotidien

Les hôtes modernes utilisent MSI ou MSI-X, Au lieu d'envoyer des signaux de ligne classiques (lignes IRQ). MSI transmet le message sous forme d'écriture en mémoire et réduit ainsi la latence et la sensibilité aux perturbations. MSI-X étend le concept : plus de messages, des files d'attente séparées, une répartition plus ciblée sur les noyaux. Cela permet de réduire les collisions d'interruptions et d'améliorer la sécurité. Mise à l'échelle à haut débit. J'active MSI-X pour les cartes réseau et les contrôleurs NVMe, dans la mesure où les pilotes et le micrologiciel le supportent de manière stable.

mécanisme Max a été créé. Messages Adressage Répartition sur les noyaux Effet typique
IRQ patrimoniale 1 par appareil/ligne Signal de ligne Limité Plus haut Latence, plus de collisions
MSI Jusqu'à ~32 Écriture en mémoire (16 bits) Bon Moins d'overhead, des chemins plus stables
MSI-X Jusqu'en 2048 Écriture en mémoire (32 bits) Très bon Plus fin Distribution, parallélisme plus élevé

DMA, DPC et le bon chemin de données

Le DMA permet aux appareils d'enregistrer des données directement dans le Mémoire le CPU ne déclenche plus que des routines de traitement. Cela permet d'économiser des interruptions, car moins d'états intermédiaires doivent être signalés. Je veille à ce que les DPC concentrent le travail réel au lieu d'en faire trop dans l'ISR. Ainsi, le temps dans la section critique reste court et les Latence de manière plus prévisible. Au total, l'unité centrale gagne plus de temps pour la logique de l'application.

Configurer de manière ciblée le RSS et l'affinité CPU

Receive Side Scaling répartit les queues de réseau et leurs interruptions sur plusieurs noyaux. Je lie chaque file d'attente, y compris l'interruption, le DPC et le thread utilisateur, au même noyau ou au même cluster de noyaux afin d'éviter les réveils croisés. Si différents noyaux interviennent dans un flux, les échecs de cache et les changements de contexte augmentent. Un plan d'affinité structuré empêche sensiblement de telles pertes de friction. Pour ceux qui souhaitent approfondir le sujet, voici un guide compact Affinité avec le CPU-Aperçu des configurations d'hébergement.

Désamorcer les interruptions de stockage et les chemins d'E/S

Le stockage génère également beaucoup Interruptions, surtout avec beaucoup de petites IOPS. J'utilise MSI-X sur des contrôleurs NVMe et j'attribue des queues à des noyaux fixes afin que les entrées et les sorties restent locales. En outre, un Planificateur d'E/S, La charge par file d'attente est lissée. Les variantes Deadline, BFQ ou MQ réagissent très différemment en fonction de la charge de travail. En testant proprement, on réduit la gigue et on augmente le temps de réponse. Débit.

Tempêtes de réseau, floods SYN et modération des interruptions

Des flots soudains de paquets poussent ISR-et privent le CPU d'air. J'active la modération des interruptions sur la carte réseau de manière à ce que les paquets arrivent en rafales raisonnables, sans générer de pics de latence. Dans les scénarios de DoS, une connexion résiliente stabilise le trafic. Défense SYN-Flood le tableau de connexion de manière précoce. En même temps, je mesure si la modération elle-même réagit trop lentement - dans ce cas, j'ajuste les valeurs. L'objectif est d'obtenir un flux de paquets calme qui permette aux DPC de se déplacer de manière régulière. nourrit.

Monitoring : lire les chiffres et agir

Je commence par quelques points clairs Métriques: utilisation totale du CPU, temps d'interruption, temps DPC, changement de contexte et file d'attente du processeur. Si le CPU reste la plupart du temps en dessous de 50%, je réagis calmement ; à 50-80%, j'observe les pics et les points chauds ; au-dessus de 80%, je planifie une mise à l'échelle ou un réglage. Si le temps d'interruption dépasse 30%, je vérifie les pilotes, le firmware et les affinités. Un contrôle de la latence pour l'audio/vidéo montre indirectement à quel point le noyau réagit de manière déterministe. Important : je ne modifie qu'une Variable par test et mesure à nouveau ensuite.

Topologie NUMA et localité PCIe

Sur les hôtes multi-socket, je détermine toujours les affinités d'interruption dans le contexte de la NUMA-topologie de la carte. Une carte réseau ou un contrôleur NVMe est physiquement attaché à un complexe PCIe racine et donc à un nœud NUMA. Je place les files d'attente et leurs interruptions sur lointain noyaux, les données passent par des liens UPI/QPI - les latences augmentent, la bande passante diminue. Je vérifie donc à quel nœud NUMA un périphérique est associé, je lie ses files d'attente aux noyaux locaux et je m'assure que les threads utilisateurs associés utilisent le même nœud. Sous Windows, je tiens compte des groupes de processeurs et du paramétrage du périphérique pour le nœud NUMA préféré ; sous Linux, je lie les IRQ, les softirqs et les threads d'application de manière cohérente au nœud local. Résultat : moins de trafic entre les nœuds, une meilleure stabilité. Jitter-et des temps de latence prévisibles dans le pire des cas.

Utiliser correctement les offloads, NAPI et le coalescing

Les offloads sont de puissants leviers contre les inondations d'interruptions - mais ils doivent être utilisés pour le Charge de travail s'adapter à la situation. En gros, cela se résume ainsi : Le TSO/GSO déplace la segmentation vers la NIC, le LRO/GRO regroupe les segments entrants, le RSC sur l'hôte agit de manière similaire au LRO. Pour les transferts en vrac (sauvegarde, réplication), ces fonctionnalités augmentent le débit et réduisent nettement le taux ISR. Pour les flux critiques en termes de latence (RPC, trading, VoIP), les grandes agrégations peuvent toutefois Temps de réponse prolonger la durée de vie. J'opte donc pour des réglages modérés : GRO oui, mais sans exagérer ; LRO seulement si aucun appareil mid-path ou pare-feu ne pose problème ; laisser TSO/GSO actif en règle générale.

NAPI sur Linux passe du mode interruption pure au mode poll à partir de la charge. Cela permet de lisser les pics et de garder le CPU occupé dans le chemin DPC au lieu de déclencher des milliers de courtes ISR. Avec Modération des interruptions (Coalescing), un plan se dessine : des minuteries courtes pour les profils interactifs, des minuteries plus longues pour le vrac. Je teste les intervalles par paliers de quelques microsecondes, j'observe les drops, les niveaux de remplissage des anneaux et les latences et trouve ainsi le "sweet spot". Dans la pile de stockage, des vis de réglage analogues (Queue-Depth, NCQ, optimisations blk-mq) fournissent le même effet : moins de staccato, plus de Efficacité.

Équilibrage IRQ vs. épinglage statique

L'équilibrage automatique des IRQ répartit la charge de manière acceptable - mais pas parfaite. Dans les environnements web homogènes, je le laisse souvent fonctionner et ne contrôle que les hotspots. Dans les configurations à latence critique ou asymétriques, il est épinglage statique de la réflexion : Je définis des ensembles fixes de processeurs par file d'attente et par périphérique, je les maintiens cohérents grâce aux redémarrages et je minimise les déplacements des softirqs. En outre, je réserve des noyaux „housekeeping“ pour le travail en arrière-plan (timer, Kthreads), afin que les noyaux de performance restent libres. Sous Windows, j'utilise de manière ciblée le steering d'interruption et les masques d'affinité par file d'attente ; sous Linux, je travaille avec l'affinité per-IRQ et le contrôle Softirq. La devise : autant d'automatisme que nécessaire, autant de Déterminisme que possible.

Virtualisation et SR-IOV/virtio

Dans les VM, il y a des coûts supplémentaires : les interruptions virtuelles signifient Exits VM, les retards d'ordonnancement et les files d'attente partagées. J'épingle les vCPU à forte intensité d'E/S sur les pCPU correspondants, j'évite l'overcommit sur les hôtes d'E/S et je sépare les threads de plan de données de la charge de gestion. Dans la mesure du possible, j'utilise SR-IOVLes fonctions virtuelles apportent MSI-X jusque dans la VM de l'invité et soulagent le chemin de l'hyperviseur. Pour les charges de travail génériques, virtio fournit des résultats solides avec l'accélération vhost ; dans les scénarios à haut débit, je mappe les files d'attente 1:1 sur les vCPU et je garde les affinités cohérentes de l'invité à l'hôte. Important : les mêmes règles concernant le RSS, le coalescing et le NUMA s'appliquent également aux VMs - seules les Transparence est plus faible, c'est pourquoi je mesure plus étroitement.

Gestion de l'énergie et latences déterministes

Les fonctions d'économie d'énergie sont bonnes pour le bilan mais mauvaises pour les Budgets de latence. Les C-States profonds prolongent le temps de réveil, les changements de fréquence agressifs provoquent de la gigue. Sur les hôtes avec des SLO stricts, je définis des profils de performance, je limite les C-States profonds des paquets et je n'autorise le turbo que là où la réserve thermique est suffisamment importante. Les décisions concernant les temporisateurs (temporisateurs à haute résolution vs. fréquence d'interruption plus faible) influencent également la quantité et la cadence du travail du noyau. Dans les configurations proches du temps réel, les modes sans horloge et les noyaux isolés sont utiles : les threads d'application sur des noyaux isolés, le travail système sur des noyaux de „housekeeping“ dédiés - de cette manière, le temps critique est conservé. Hotpath exempts de tirs parasites.

Outils et méthodologie de mesure par OS

Je tiens mes Chaîne de diagnostic léger et reproductible. Sous Linux, je commence par /proc/interrupts et /proc/softirqs, je vérifie les compteurs per-queue via ethtool et je regarde les paramètres de coalescence et de déchargement. mpstat, vmstat et sar montrent les tendances des macros ; perf détecte les hotspots dans les ISR/DPC. Je corrèle les compteurs de paquets et de drop avec les temps du noyau et les métriques de flux. Sous Windows, les indicateurs de performance sur le temps d'interruption/DPC, les interruptions/sec et les DPC/sec fournissent une image propre ; les traces montrent quels pilotes imposent la cadence. Ce qui est important, c'est le partage Échelle de tempsJe synchronise tout pour que les pics, les drops et les sauts de latence correspondent.

Playbook de dépannage et anti-patronage

Ma démarche est cohérente : d'abord Observer, puis une hypothèse, puis un changement. Causes typiques : une file d'attente ou un périphérique avec un taux ISR excessif, un firmware défectueux, des valeurs de coalescence trop élevées (système tenace) ou trop basses (tempête ISR), des offloads qui regroupent trop de données ou des threads qui tirent des files d'attente à travers les nœuds NUMA. J'isole le périphérique concerné, je teste des paramètres par défaut conservateurs, je modifie les pilotes/BIOS et je répartis proprement la charge. Anti-pattern : tout changer en même temps, des rollbacks malpropres, pas de ligne de base ou des valeurs de mesure sans contexte. Celui qui persévère dans une Variable une par une, on arrive rapidement à une configuration stable.

Blueprints pour les hôtes 10/25/100G et NVMe

Pour les cartes réseau 10G, je calcule 4 à 8 files d'attente RSS, en fonction de la génération de CPU et du profil des paquets. Je commence à coalescer modérément (par ex. des microsecondes à deux chiffres), GRO activé, LRO prudent. À 25G, je passe à 8-16 files d'attente et je garde l'affinité strictement locale à NUMA. A partir de 40/100G, l'architecture de la file d'attente devient la Mission principaleBeaucoup de files d'attente, une affectation propre par cœur, des charges utiles actives, la NAPI intervient sous charge. Pour le stockage NVMe, je mappe au moins une file d'attente par cœur et je garde la profondeur de la file d'attente adaptée à la charge de travail - les petites E/S bénéficient de plus de parallélisme, les gros transferts séquentiels d'une politique de coalescence stable et d'un ordonnanceur qui lisse les bursts. L'objectif reste le même : des latences constantes, pas de noyaux chauds, pas d'anneaux qui débordent.

Liste de contrôle pratique pour des résultats rapides

Je mets d'abord à jour Pilote et le BIOS/firmware, car les états défectueux font souvent grimper la charge d'interruption. Ensuite, je passe à MSI-X si possible et répartis proprement les files d'attente sur les noyaux. Je configure RSS de manière à ce que les affinités de flux soient correctes et que les hotpaths restent cohérents. Sur la carte réseau, j'adapte la modération au profil de trafic et j'observe l'effet sur les latences. Si je continue à trouver des aberrations, je recherche le matériel défectueux, les mauvaises options ou les appareils problématiques par une procédure d'exclusion et une analyse séparée. Profilage.

Évaluer le rapport coût-bénéfice de manière réaliste

Tous les systèmes n'ont pas besoin d'un maximum de Peaufinage. Je donne la priorité aux hôtes avec une charge de paquets élevée, beaucoup de petits IOPS ou une latence étroite. Quelques heures de réglage y sont très rentables, car moins de surcharge d'interruption libère immédiatement le CPU pour l'application. Sur les serveurs non critiques, une configuration de base solide avec des pilotes actuels et MSI-X suffit. Ce sont les valeurs mesurées qui me guident, pas l'intuition ou l'expérience. Présomptions.

Résumé : Ce que je mets dans l'entretien quotidien

J'observe systématiquement Interruption- et DPC, je tiens les pilotes et le micrologiciel à jour et j'utilise MSI-X lorsque c'est possible. Je planifie les RSS et les affinités par charge de travail afin que les flux, les DPC et les threads restent locaux. J'adapte la modération de la carte réseau aux modèles de trafic, je répartis proprement les files d'attente de stockage et j'utilise des chemins d'E/S appropriés. Si le monitoring montre des aberrations, je travaille en ligne droite à travers les pilotes, le matériel et la configuration. Ainsi, le serveur de gestion des interruptions reste prévisible et mes charges de travail fonctionnent de manière stable. Performance.

Derniers articles