...

Architecture NUMA : pourquoi elle joue un rôle important dans les serveurs modernes

Le Architecture NUMA détermine la vitesse à laquelle les serveurs modernes fournissent de la mémoire aux threads et la capacité des charges de travail à s'adapter en cas de forte sollicitation. Je montre pourquoi les accès à la mémoire locale dominent la latence et la bande passante, comment les hyperviseurs utilisent NUMA et quels paramètres dans les machines virtuelles permettent d'obtenir des gains de performance directs.

Points centraux

Je résume brièvement les principales conclusions et souligne les facteurs qui ont le plus d'impact dans les centres de données.

  • Mémoire locale Réduit la latence et augmente le débit
  • nœud NUMA Structurer efficacement les processeurs et la mémoire vive
  • Taille du vCPU Adapter la taille du nœud par VM
  • NUMA virtuel Transmettre au système d'exploitation invité
  • Règles de tension Définir pour les besoins importants en RAM

Je me concentre systématiquement sur Latence et la proximité des données, car c'est là que se décide la performance du serveur. De grands sockets, de nombreux cœurs et beaucoup de RAM ne servent pas à grand-chose si les threads attendent constamment des zones de mémoire distantes. Je dimensionne les machines virtuelles de manière à ce qu'elles s'adaptent à un nœud NUMA et que l'allocation de mémoire reste locale. Je prends en charge les fonctionnalités de l'hyperviseur de manière ciblée, au lieu de tout activer globalement. Je sécurise ainsi Mise à l'échelle sans surprises lors des pics de charge.

Ce qui caractérise vraiment NUMA

Je pense en Nœuds: Chaque nœud NUMA combine des cœurs de processeur et une zone RAM locale avec des chemins d'accès très courts. Si un thread trouve les données dans le cache L1, L2 ou L3, tout fonctionne extrêmement rapidement ; si l'ensemble de données se trouve dans la RAM locale, la latence reste faible. Cependant, si le thread accède à un autre nœud, le temps d'attente augmente et le débit diminue. Ce sont précisément ces différences qui font Non uniforme Accès mémoire désactivé. J'organise donc les charges de travail de manière à ce que la majeure partie des accès reste locale.

Pourquoi l'UMA atteint ses limites

UMA partage un chemin d'accès ce qui génère des embouteillages lorsque le nombre de cœurs augmente. Chaque cœur supplémentaire s'ajoute aux mêmes files d'attente et entre en concurrence pour la bande passante. Dans de nombreuses configurations anciennes, cela entraînait une accumulation de latence jusqu'à ce que l'utilisation du CPU soit élevée, mais que l'application réagisse lentement. Cela donne l'impression que le CPU est à la limite de ses capacités, alors que le goulot d'étranglement se situe en réalité au niveau de l'accès à la mémoire. NUMA résout précisément ce problème. Blocages par des chemins locaux et une topologie en nœuds.

NUMA vs UMA : aperçu des différences

Je présente volontiers les principales différences dans un aperçu compact. Tableau fixe, afin que les décisions puissent être prises plus rapidement. Cet aperçu montre ce qui est important en matière d'architecture, de latence et d'évolutivité. Il m'aide à dimensionner de nouveaux hôtes et à rechercher des erreurs dans des environnements productifs. Ceux qui comprennent clairement la différence entre l'accès local et l'accès à distance prennent de meilleures décisions en matière de personnalisation des machines virtuelles et d'allocation de RAM. C'est précisément là que se joue la différence. Performance en charge.

Critère NUMA UMA Effet pratique
accès à la mémoire Local ou distant Uniforme Les accès locaux sont plus rapides ; les accès distants entraînent une latence.
Mise à l'échelle Très bon avec des nœuds Limité tôt Plus de cœurs évoluent de manière plus fiable avec NUMA
Topologie Plusieurs nœuds Pool uniforme Une planification tenant compte de la topologie est nécessaire
hyperviseur NUMA virtuel disponible Moins pertinent Le système d'exploitation invité peut planifier en tenant compte de NUMA
réglage fin vCPU/RAM par nœud Réglage global Les machines virtuelles adaptées aux nœuds garantissent la stabilité

NUMA dans les environnements virtuels

Je laisse l'hyperviseur gérer les Topologie au système d'exploitation invité afin que le planificateur et la gestion de la mémoire puissent planifier localement. Virtual NUMA montre à l'invité les limites de ses nœuds, ce qui permet aux bases de données, aux JVM et aux travailleurs .NET d'organiser leurs tas et leurs threads de manière plus avantageuse. Cela me permet d'éviter les accès à distance coûteux et de maintenir une latence stable. Dans les configurations sensibles, je combine cela avec une stratégie de pinning cohérente et une allocation fixe de RAM. Pour des temps de réponse extrêmement courts, j'utilise en plus Hébergement à micro-latence pour réduire davantage la gigue.

Meilleures pratiques pour la taille des machines virtuelles et l'allocation des processeurs

Je dimensionne vCPU de manière à ce qu'une VM s'intègre dans un nœud NUMA ou ne le touche que très légèrement. Exemple : si un hôte dispose de deux nœuds à 20 cœurs, je planifie de préférence les VM avec 4 à 16 vCPU au sein d'un nœud. Au-delà, on risque des accès à distance et des temps d'attente inutiles. Je répartis la RAM de manière aussi statique que possible afin que le système d'exploitation invité conserve ses pages en local. Pour les charges de travail à forte composante single-thread, j'intègre la bonne stratégie de cœurs et j'utilise des analyses telles que Single-Thread vs. Multi-Core.

Avantages concrets pour le matériel d'hébergement

Grâce à une planification NUMA rigoureuse, j'augmente la densité par hôte, sans sacrifier les temps de réponse. Dans de nombreux centres de données, cela permet d'exploiter nettement plus de machines virtuelles par socket, tout en garantissant la réactivité des applications. La réduction de la latence a un impact direct sur l'expérience utilisateur et le débit par lots. Les coûts par charge de travail diminuent grâce à une utilisation plus efficace du temps CPU et de la RAM. En choisissant judicieusement son matériel, on bénéficie en outre d'une technologie moderne. Matériel d'hébergement web haute performance avec une bande passante mémoire élevée.

Optimisation de la charge de travail : bases de données, caches, conteneurs

Je veille à ce que Bases de données conserver leurs tas localement et calculer les threads de travail sur „ leur “ nœud. Pour les moteurs SQL, les caches en mémoire et les JVM, il est intéressant d'attribuer de manière fixe les CPU et de réserver la mémoire. L'orchestration des conteneurs bénéficie des affinités entre nœuds, afin que les pods utilisent les chemins d'accès à la mémoire les plus courts. En cas d'E/S intensives, je mise sur des attributions NVMe proches de NUMA afin de conserver les données à proximité des nœuds. Les chemins d'accès restent ainsi courts et les Temps de réaction sympathique.

Surveillance et dépannage avec NUMA

Je mesure Latence et les accès à distance de manière ciblée, au lieu de me concentrer uniquement sur les pourcentages d'utilisation du CPU. Des outils m'indiquent, pour chaque nœud, combien de pages sont stockées à distance et quels threads génèrent une pression sur la mémoire. Si les échecs à distance augmentent, j'ajuste la taille du vCPU, les affinités ou l'allocation de RAM. Si le débit reste faible malgré des réserves CPU élevées, cela est souvent dû aux chemins d'accès à la mémoire. La visibilité au niveau des nœuds est pour moi le moyen le plus rapide d'atteindre Causes, pas seulement aux symptômes.

NUMA Spanning : utilisation correcte

J'active Spanning Spécifiquement pour les VM ayant des besoins très importants en RAM ou une bande passante exceptionnelle. La VM peut alors obtenir de la mémoire sur plusieurs nœuds, ce qui rend possible les instances uniques avec une empreinte massive. Le prix à payer est un accès distant occasionnel, que j'atténue avec des affinités CPU et une plus grande part de localité de page. Pour les charges mixtes, je préfère choisir plusieurs VM de taille moyenne plutôt qu'une très grande instance. Ainsi, Planification dans la vie quotidienne.

Licences, densité et coûts réels

Je note Coûts non pas au niveau de l'hôte, mais par charge de travail et par mois en euros. Lorsque NUMA augmente la densité des machines virtuelles, les coûts fixes par instance diminuent et les réserves de puissance augmentent. Cela a un impact sur les licences par cœur ainsi que sur les coûts d'assistance et d'énergie. En réduisant les accès à distance, vous raccourcissez le temps de calcul et économisez de l'énergie pour une même tâche. Au final, ce qui compte, c'est le Bilan global en euros par résultat, et non pas seulement en euros par serveur.

Bien comprendre la topologie matérielle et les interconnexions

Je fais référence à la physique Topologie dans ma planification. Les serveurs modernes utilisent des conceptions de processeurs en plusieurs parties et relient des chiplets ou des puces via des interconnexions. Cela signifie que tous les cœurs n'ont pas le même chemin vers chaque module RAM, et même au sein d'un socket, il existe des chemins préférentiels. Plus le trafic passe par les liaisons inter-sockets, plus les coûts augmentent. Latence et la charge de cohérence. Je vérifie donc combien de canaux mémoire sont actifs par nœud, si tous les emplacements DIMM sont équipés de manière symétrique et comment les nœuds sont connectés dans la carte mère. Les fonctionnalités Sub-NUMA, qui divisent les nœuds en domaines plus petits, peuvent désencombrer les points chauds lorsque les charges de travail sont clairement segmentées. J'observe également la Topologie L3: Si les threads et leurs données se trouvent dans différents domaines de cache, le transfert de cache seul entraîne une perte de performance notable. Un simple test de bande passante et un aperçu de la topologie permettent de déterminer rapidement si la plateforme offre la localité attendue ou si les interconnexions deviennent un goulot d'étranglement.

Options du micrologiciel et du BIOS avec effet

Je vérifie dans le BIOS que Entrelacement de nœuds est désactivé afin que la structure NUMA reste visible. J'utilise le clustering Sub-NUMA ou des modes comparables de manière ciblée lorsque les charges de travail comportent de nombreuses tâches de taille moyenne clairement séparées. Pour obtenir des latences cohérentes, je choisis des profils énergétiques axés sur les performances et réduis les États C et évite le stationnement agressif. J'optimise l'équipement de mémoire pour une pleine Bande passante du canal mémoire; les configurations DIMM asymétriques ont un impact direct sur le débit et le temps d'attente. Je vérifie également les options Prefetcher et RAS : certains mécanismes de protection augmentent la latence sans servir la charge de travail. Important : je teste chaque ajustement du BIOS avec une charge réelle, car les micro-effets dus aux caches et aux interconnexions n'apparaissent souvent que sous pression.

Optimisation du système d'exploitation invité et du runtime : du premier contact aux pages géantes

Dans Gast, j'utilise Première touche-Allocation à mon avantage : les threads initialisent „ leur “ mémoire afin que les pages soient créées localement. Sous Linux, j'active ou désactive le rééquilibrage NUMA automatique en fonction de la charge de travail ; les systèmes proches des bases de données bénéficient souvent d'une connexion stable, tandis que les travailleurs Web distribués peuvent supporter de faibles migrations. Avec numactl ou Task-Pinning, je connecte les services aux nœuds et définis membind-Directives. Pages géantes Réduire la pression TLB ; pour les bases de données critiques en termes de latence, je privilégie les pages statiques volumineuses et la mémoire chaude (Pre-Touch) afin d'éviter les pics de défauts de page. J'utilise les pages volumineuses transparentes en mode „ madvise “ ou je les désactive si elles génèrent des latences de défragmentation, en fonction du moteur. Je contrôle Affinités IRQ et distribue les interruptions réseau et NVMe aux nœuds appropriés ; RPS/XPS et les files d'attente multiples aident à maintenir la cohérence des chemins de données. Sous Windows, j'utilise des groupes de processeurs et Soft-NUMA dans la pile, je veille à ce que les pages soient verrouillées en mémoire pour les services gourmands en mémoire et j'active le GC serveur dans .NET. Pour les JVM, j'utilise des heuristiques NUMA, des tas pré-touchés et je contrôle l'affinité des threads afin que le GC et les workers utilisent les mêmes nœuds.

Aligner correctement les paramètres spécifiques à l'hyperviseur

Je passe le Topologie vNUMA à la structure physique. Je sélectionne les paramètres „ Sockets “, „ Cores per Socket “ et „ Threads per Core “ de manière à ce que l'hyperviseur ne divise pas la VM en nœuds. Pour les instances sensibles à la latence, je réserve de la RAM afin d'éviter le ballooning et le swapping, et je sécurise les ressources pCPU via l'affinité ou des options de planification appropriées. Attention lors de l'ajout à chaud de CPU ou de mémoire : de nombreuses plateformes désactivent ainsi vNUMA dans l'invité, ce qui entraîne des accès à distance cachés. Je planifie la migration en direct de manière à ce que les hôtes cibles aient une topologie NUMA compatible, et je laisse aux VM le temps, après la migration, de Localisation de la page (pré-touch, préchauffage). Dans les environnements KVM, j'utilise les options de réglage NUMA et cpuset-Cgroups ; dans d'autres hyperviseurs, des outils tels que exstop permettent de visualiser en temps réel la répartition des vCPU et les hits des nœuds.

Ne gaspillez pas la localité PCIe et E/S

Je classe NVMe-Les lecteurs, les HBA et les NIC sont attribués au nœud sur lequel s'exécutent les threads de calcul. Je lie les files d'attente SR-IOV ou vNIC aux cœurs du même nœud et contrôle les interruptions en conséquence. Pour les débits de paquets élevés, je fais évoluer les files d'attente de réception/transmission et les répartis de manière cohérente sur les cœurs locaux. Pour les piles de stockage, je veille à ce que les threads de travail pour les soumissions et les achèvements d'E/S fonctionnent sur le même nœud afin que le chemin d'accès aux données ne traverse pas l'interconnexion. Je planifie également le multipathing et le RAID logiciel en fonction des nœuds ; un chemin „ plus court “ l'emporte presque toujours sur un chemin „ plus large “ avec des accès externes. Cela me permet de réduire la gigue et d'apporter sous la charge d'E/S la temps CPU là où elle a un effet.

Planification des capacités, surengagement et fonctionnalités mémoire

Je préfère exécuter les charges de travail orientées latence sans Overcommit sur la RAM et modérément sur le vCPU. Le ballonage, la compression et l'échange d'hyperviseur génèrent des accès externes ou des pics de défauts de page, ce que je souhaite justement éviter. Le partage transparent de pages est inefficace dans de nombreuses configurations et peut masquer la véritable localité. Je calibre le mélange des VM de manière à ce que plusieurs instances gourmandes en bande passante mémoire n'entrent pas en collision sur le même nœud. Pour les moteurs en mémoire, je prévois une marge généreuse. Réservations et, lorsque cela s'avère utile, des pages volumineuses dans l'invité que l'hyperviseur peut transmettre. Ainsi, le taux de réussite TLB et les temps d'accès restent prévisibles.

Migration en direct et haute disponibilité

Je tiens compte du fait qu'une Migration Je détruis temporairement la localisation latérale d'une VM. Après le transfert, je réchauffe les piles critiques et laisse les tâches en arrière-plan reconstruire les hotsets. Je planifie les hôtes cibles avec une topologie NUMA similaire afin de ne pas avoir à redécouper vNUMA. Pour les cas HA avec du matériel hétérogène, je définis des politiques : soit j'accepte une latence temporairement plus élevée, soit je donne la priorité aux hôtes avec une taille de nœud compatible. Il est important d'observer après la migration : si les proportions de pages distantes augmentent, j'ajuste les affinités ou je déclenche le pré-faute jusqu'à ce que le Localité à nouveau.

Modèles de diagnostic pratiques

Je reconnais les problèmes NUMA typiques à quelques signes : le CPU „ chauffe “, mais le Instructions par cycle restent faibles ; la latence varie par vagues ; certains threads bloquent les accès à la mémoire, même si les cœurs sont libres. Dans ce cas, je vérifie les accès à distance, l'utilisation de l'interconnexion, les erreurs TLB et la répartition des threads actifs par nœud. Je corrèle la charge d'interruption avec les cœurs qui supportent l'application et je vérifie si les caches entre les nœuds sont constamment invalidés. Un simple contrôle consiste à réduire la VM à un nœud : si les latences diminuent immédiatement, la cause était le spanning ou la planification. De même, des tests dédiés révèlent la bande passante RAM par nœud et montrent si l'équipement DIMM ou les options BIOS ralentissent le système.

Liste de contrôle pratique

  • Comprendre la topologie : nœuds, canaux mémoire, mappage PCIe, domaines de cache
  • Vérifier le BIOS : Node Interleaving désactivé, profil énergétique Performance, C-States plat
  • Réduire les VM : vCPU par VM ≤ taille du nœud, vNUMA correct, tenir compte de l'ajout à chaud
  • Sécuriser la RAM : réservations pour les charges de travail à latence, pages géantes lorsque cela est pertinent
  • Définir l'affinité : lier les threads, les IRQ et les files d'attente d'E/S au même nœud
  • Conteneurs/pods : utiliser l'affinité des nœuds, le gestionnaire CPU et la reconnaissance de la topologie
  • Spanning uniquement de manière ciblée : accompagner les grandes instances avec des politiques et une surveillance
  • Planifier la migration : topologie cible adaptée, pré-touch des tas, observer la localité
  • Renforcer la surveillance : accès à distance, bande passante par nœud, utilisation de l'interconnexion
  • Tests réguliers : contrôles de bande passante/latence après les changements de micrologiciel ou d'hôte

Derniers articles