Numactl

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Mémoire, NUMA, placement des processus
Commande numactl
Paquet numactl (RHEL/Debian/Ubuntu)
Contexte Serveurs multi-socket (NUMA) — bases de données, JVM, virtualisation
Voir aussi Numastat (statistiques d'allocation mémoire par nœud)

numactl contrôle la politique NUMA (Non-Uniform Memory Access) d'un process : sur quel(s) nœud(s) il s'exécute et sur quel(s) nœud(s) sa mémoire est allouée. Contrairement à Numastat, qui se contente d'observer après coup l'allocation mémoire par nœud, numactl agit en amont, au lancement du process (ou sur un process déjà en cours pour la partie CPU), en imposant une politique de placement.

Topologie et politique courante

numactl --hardware   # nombre de nœuds NUMA, CPU par nœud, mémoire par nœud, matrice de distances
numactl --show       # politique NUMA courante du shell (cpubind, membind, mode d'allocation)

--hardware donne la topologie physique du serveur : c'est la même information que celle utilisée en tête de la fiche Numastat pour interpréter les hits/miss par nœud. --show, sans argument, affiche la politique héritée par le shell courant (utile pour vérifier qu'aucune contrainte NUMA n'est déjà active avant de lancer un test).

Épingler un process à un nœud NUMA (CPU + mémoire)

numactl --cpunodebind=0 --membind=0 mysqld

Force le process à s'exécuter uniquement sur les CPU du nœud NUMA 0, et à n'allouer sa mémoire que sur ce même nœud. C'est le cas d'usage le plus courant pour éliminer les accès mémoire distants (interconnexion inter-socket) sur une base de données ou tout process mono-instance qui ne doit pas migrer d'un socket à l'autre.

Épingler à des CPU précis

numactl --physcpubind=0,1,2,3 program

Restreint l'exécution à une liste précise de CPU logiques, plus fin que --cpunodebind qui raisonne au niveau du nœud entier. Utile pour partager un nœud NUMA entre plusieurs process en leur réservant chacun un sous-ensemble de cœurs.

Répartir la mémoire sur tous les nœuds (interleave)

numactl --interleave=all program

Répartit les allocations mémoire du process sur l'ensemble des nœuds NUMA disponibles, au lieu de privilégier un nœud local. Contre-intuitif au premier abord (ça renonce volontairement à la localité mémoire), mais utile pour les process qui allouent une grosse zone mémoire partagée entre plusieurs threads répartis sur tous les sockets (ex. shared buffers PostgreSQL) : mieux vaut une latence moyenne homogène qu'un nœud unique saturé pendant que les autres restent inutilisés.

Vérifier l'effet du placement

Une fois le process lancé sous numactl, Numastat permet de confirmer que le placement voulu est bien effectif :

numastat -p mysqld   # mémoire réellement allouée par nœud, à comparer au binding demandé

Si --membind=0 a été demandé mais que numastat -p montre une part significative de mémoire sur un autre nœud, c'est que le binding n'a pas pu être respecté (mémoire déjà saturée sur le nœud cible au moment de l'allocation) — voir Numastat pour le détail des colonnes et le diagnostic.

Voir aussi

  • Numastat — observer l'effet du placement NUMA après coup (hits/miss, mémoire par nœud)
  • Vmstat — statistiques mémoire et CPU globales, sans distinction NUMA
  • Processeur — informations CPU, dont la topologie multi-socket