Aller au contenu
EuroVPSEuroVPS

Pourquoi une VM plus grande qu'un socket CPU est souvent plus lente

Comment NUMA fonctionne sur un hôte à deux sockets, pourquoi une VM à cheval sur les deux paie à chaque accès mémoire, et comment lire la topologie.

Par EuroVPS Engineering

5 min de lecture
Why a VM bigger than one CPU socket is often slower

Quand une machine virtuelle est lente, le réflexe est de lui donner plus de cœurs. Sur un serveur moderne à deux sockets, il y a un point où ce réflexe se retourne contre vous, et la VM plus grosse tourne plus lentement que la plus petite qu'elle a remplacée. Ce point est la taille d'un socket CPU, et la raison s'appelle NUMA.

Ce qu'est NUMA, en un paragraphe

Un serveur à deux processeurs est en réalité deux ordinateurs qui partagent un pont. Chaque socket a ses propres contrôleurs mémoire et sa propre banque de mémoire directement attachée. Un cœur qui lit de la mémoire attachée à son propre socket l'obtient à vitesse locale. Un cœur qui lit de la mémoire attachée à l'autre socket doit traverser l'interconnexion entre les sockets, et cet accès est plus lent. Cette disposition est l'accès mémoire non uniforme : chaque cœur peut atteindre toute la mémoire, mais pas au même coût. Chaque socket avec sa mémoire est un nœud NUMA.

Pourquoi franchir la frontière coûte plus qu'il n'y paraît

Un accès mémoire distant prend environ 1,7 fois plus de temps qu'un accès local. C'est déjà une lourde pénalité pour tout ce qui touche souvent la mémoire, c'est-à-dire presque tout. Et ce n'est pas toute la facture :

  • Cohérence de cache. Les deux sockets doivent garder leurs caches cohérents. Quand des threads des deux côtés travaillent sur les mêmes données, les lignes de cache rebondissent à travers l'interconnexion, et chaque rebond est un blocage.
  • Saturation de l'interconnexion. Le lien entre les sockets a une bande passante finie. Une VM chargée répartie sur les deux sockets le dispute à tout le reste sur l'hôte.
  • Ordonnancement. Une VM dont les vCPU ne peuvent pas tous s'exécuter à la fois sur un socket attend que l'hyperviseur trouve de la place sur les deux, et ses threads atterrissent là où il y a de l'espace, souvent loin de leurs données.

Ces effets se composent plutôt qu'ils ne s'additionnent. Une charge qui monterait bien en charge à l'intérieur d'un socket peut perdre une grande part de son débit une fois étalée sur deux, et les cœurs supplémentaires que vous avez ajoutés paient pour ce privilège.

Lisez la topologie de votre hôte

Avant de dimensionner quoi que ce soit, regardez ce que l'hôte a réellement :

lscpu | grep -E 'Socket|Core|Thread|NUMA'
numactl --hardware

Sortie typique sur un hôte à deux sockets :

Thread(s) per core:  2
Core(s) per socket:  18
Socket(s):           2
NUMA node(s):        2
NUMA node0 CPU(s):   0-17,36-53
NUMA node1 CPU(s):   18-35,54-71

Les chiffres qui comptent sont les cœurs par socket et la mémoire par nœud, que numactl --hardware affiche avec une table de distances. Les distances montrent de combien un accès distant coûte plus qu'un accès local sur cette machine précise.

Dimensionnez sur les cœurs physiques, pas sur les hyper-threads.

Les deux règles de dimensionnement

De la topologie découlent deux règles faciles à énoncer et qu'il vaut la peine de ne jamais enfreindre :

  • Une VM ne reçoit jamais plus de vCPU qu'un socket n'a de cœurs physiques. Laissez de la marge pour l'hyperviseur lui-même, donc sur un socket de dix-huit cœurs un plafond raisonnable est quelques cœurs en dessous.
  • Une VM ne reçoit jamais plus de mémoire qu'un nœud NUMA n'en sert. Sinon une partie de sa mémoire est distante par construction, quoi que fasse l'ordonnanceur.

Une VM qui respecte les deux règles peut vivre entièrement dans un nœud, et un bon hyperviseur l'y gardera.

Vérifiez où vit réellement une VM en marche

Sur un hôte KVM, vous pouvez voir comment la mémoire d'un invité est répartie entre les nœuds :

numastat -c qemu-kvm
virsh vcpuinfo <vm-name>
virsh numatune <vm-name>

Si numastat montre une grosse VM avec une mémoire substantielle sur les deux nœuds, elle paie la pénalité d'accès distant sur une part de son travail. À l'intérieur d'un invité Linux, lscpu et numactl --hardware montrent la topologie que l'hyperviseur lui présente.

Quand un seul socket ne suffit vraiment pas

Certaines charges ont réellement besoin de plus qu'un socket ne peut donner. Il existe de meilleures réponses qu'une VM géante :

  • Montez en charge horizontalement. Deux VM qui tiennent chacune dans un nœud, derrière un load balancer ou comme membres d'un cluster, battent généralement une VM à cheval sur les deux.
  • Corrigez d'abord le goulet d'étranglement. Une VM qui semble avoir besoin de plus de cœurs attend souvent le stockage, des verrous ou un seul thread occupé. Ajouter des cœurs à une charge qui ne peut pas les utiliser ne change rien, sauf la pénalité NUMA.
  • Si elle doit être grosse, rendez-la consciente de NUMA. Présentez à l'invité une topologie virtuelle qui reflète l'hôte, deux nœuds virtuels correspondant aux deux nœuds physiques, et épinglez chaque nœud virtuel à son nœud physique. Un système d'exploitation et une application qui connaissent NUMA peuvent alors garder les threads près de leurs données. Les gestionnaires KVM d'entreprise, OLVM parmi eux, exposent l'épinglage NUMA pour cela.

Plus gros n'est de toute façon pas linéairement plus rapide

Même à l'intérieur d'un socket, doubler les vCPU double rarement le débit. Des parties de chaque charge sont séquentielles, les verrous se chargent à mesure que les threads se multiplient, les caches sont partagés, et l'hyperviseur a besoin de plus d'efforts pour ordonnancer une VM large. Doubler vaut couramment une fraction du doublement, et passé la frontière du socket cela peut devenir négatif. La façon honnête de dimensionner est d'exécuter la vraie charge à deux tailles et de mesurer. La plus petite VM gagne plus souvent que les gens ne s'y attendent.

Comment nous le faisons

Sur nos private clouds OLVM et sur chaque autre plateforme que nous exploitons, les deux règles s'appliquent à chaque VM : jamais plus de vCPU qu'un socket physique n'a de cœurs, jamais plus de mémoire qu'un nœud NUMA n'en sert, dimensionnées à partir de la topologie réelle de l'hôte. Nous dimensionnons au juste besoin de la charge au lieu d'arrondir vers le haut.

Si vos VM ont été dimensionnées au jugé, ou ont simplement grossi une demande à la fois, nous serons heureux de regarder la topologie et les chiffres avec vous.

Parler à un ingénieur

Related (rows[1])

Voir aussi : Private cloud sur KVM avec OLVM · Ingénierie de la performance et de la capacité · Cloud dédié sur Apache CloudStack, selon votre cahier des charges

Publié le 10 septembre 2026.

Toutes les notes de terrain