L'équilibrage NUMA sous Linux détermine si le Noyau Si les accès à la mémoire sont localisés automatiquement ou si je contrôle moi-même leur emplacement de manière ciblée. Dans ce guide, je vais vous montrer quand je laisse le « numa balancing » actif et quand je le désactive pour Latence- Désactive la sécurité.
Points centraux
- Automatique est utile pour les charges de travail mixtes sans optimisation NUMA.
- Désactiver en cas de pinning, de politiques statiques ou de latence élevée.
- Overhead résulte des analyses, des défaillances et des migrations.
- Configuration à contrôler via Sysctl ou les paramètres de démarrage.
- Tester et mesurer plutôt que deviner, puis prendre une décision.
NUMA en bref : latences et localité
Dans les systèmes NUMA, le matériel répartit la mémoire entre plusieurs nœuds, chacun desquels CPUs sont proches géographiquement. Les accès locaux prennent moins de temps que les accès distants, ce que je remarque immédiatement à Latence et la bande passante. Si un processus s'exécute sur un nœud, mais que les données se trouvent sur un autre, je perds de précieuses microsecondes à chaque accès. C'est précisément là qu'intervient le noyau pour optimiser la Lieu en termes de pages. Quiconque comprend le principe de base s'en rend vite compte : la proximité entre les cœurs de calcul et les données est le moyen le plus direct d'obtenir une Performance.
Fonctionnement de l'équilibrage NUMA automatique
Le noyau observe à partir de quels noyaux un processus accède aux pages, et déclenche de manière ciblée Astuce-Faults. Il identifie ainsi le nœud qui reçoit le plus d’accès et y transfère ensuite les pages correspondantes. Ces migrations réduisent les accès à distance et augmentent la disponibilité locale Taux de réussite. Je constate particulièrement cet effet avec les charges de travail dynamiques, où les threads se déplacent et où la mémoire change de place. Ceux qui souhaitent approfondir le sujet peuvent découvrir les liens entre la proximité du processeur et de la mémoire via Affinité CPU/mémoire comprendre concrètement.
Quand laisser cette option activée : charges de travail typiques
Je laisse cette fonction activée lorsque les applications ne disposent pas de leur propre logique NUMA et que les processus changer. Les candidats classiques sont les serveurs d'applications, les bases de données à charge variable et les hôtes comportant de nombreux glanage. Dans ce genre de configuration, le système automatique rapproche les pages et les fils de discussion sans que j'aie à les épingler manuellement. C'est surtout sur les serveurs à plusieurs sockets que la proportion d'accès locaux augmente sensiblement. Pour les administrateurs gérant des services hétérogènes, cela constitue un avantage certain Compromis en termes de rapidité et d'effort.
Quand désactiver : des critères clairs
Je désactive le mode automatique dès que je fais exprès de déraper ou de perdre le contrôle Politiques . Si j'utilise numactl, les cgroups ou MPOL_BIND/MPOL_PREFERRED, le choix des chemins de mémoire est déjà fixé. Dans ce cas, les « hint faults » et les migrations génèrent un surcroît inutile de Overhead. Il en va de même pour les scénarios en temps réel ou de trading haute fréquence (HFT), où chaque microseconde compte et où la prévisibilité est une priorité. Ceux qui approfondissent le choix des règles de placement ont tout intérêt à examiner les Politiques de gestion de la mémoire.
Comprendre et mesurer les frais généraux
L'équilibrage automatique génère du travail : analyses, Erreurs et les migrations de pages mobilisent du temps CPU. Cela passe presque inaperçu lorsque les accès à distance diminuent fortement, mais cela ne vaut guère la peine si la mise en page est déjà locale. Je vérifie donc toujours l'impact réel à l'aide de numastat, perf et de mesures pertinentes Benchmarks. Ce qui est intéressant, c’est l’évolution sur plusieurs minutes, et pas seulement un bref pic. Ce n’est que lorsque les mesures indiquent de manière constante que le trafic local augmente et que les latences diminuent que je conserve ce mode.
Configuration : sysctl et paramètres de démarrage
Je vérifie l'état via /proc ou Sysctl et je le modifie immédiatement si nécessaire, sans Redémarrage. Pour les tests, des commandes simples comme celles ci-dessous, que j'exécute dans la console, suffisent. À long terme, je définis cette valeur dans un fichier sysctl afin qu'elle soit conservée après un redémarrage. Si vous souhaitez définir cette valeur dès le démarrage, utilisez le paramètre du noyau `numa_balancing=enable` ou désactiver. Je consigne chaque modification et je note à quelle phase du cycle de travail je l'ai effectuée.
cat /proc/sys/kernel/numa_balancing
echo 0 > /proc/sys/kernel/numa_balancing
sysctl -w kernel.numa_balancing=1
# /etc/sysctl.d/90-numa.conf
# kernel.numa_balancing = 0
Scénarios de conteneurs et de virtualisation
Sur les hôtes hébergeant un grand nombre de machines virtuelles et de conteneurs, la mise en place automatique Localisation mettent souvent leurs atouts en valeur. Les processus démarrent et s'arrêtent, les Cgroups répartissent la charge, et le noyau conserve la mémoire plus près des cœurs actifs. Je constate cela surtout sur les grands serveurs multi-sockets comportant plusieurs nœuds. Je distingue clairement les cas particuliers impliquant un « pinning » strict d’instances individuelles et j’y désactive de manière ciblée le mode automatique. Pour une classification plus approfondie, il est utile de se pencher sur des exemples pratiques Optimisation NUMA en mode hôte.
Tableau d'aide à la décision pour la pratique
Le tableau suivant résume les scénarios types, l'impact attendu et ma position claire Recommandation. Je m'en sers comme point de départ, mais je ne les remplace jamais par les valeurs mesurées sur le système réel. Chaque environnement présente des particularités, et je ne prends de décisions qu'après avoir obtenu des résultats reproductibles Résultats certain. En procédant de manière systématique, on gagne du temps par la suite lors du dépannage et de l'optimisation. Effectuer de petits tests avant un déploiement s'avère presque toujours payant en Constance et la prévisibilité.
| Scénario | Effet typique | Ma recommandation |
|---|---|---|
| Charges de travail standard sans optimisation NUMA | Plus d'accès locaux, moins d'accès à distance Lire | Laisser actif |
| Bases de données à charge variable | Localisation dynamique des pages, modérée Scans | Laisser actif, tester |
| Temps réel strict ou HFT | La latence des erreurs de cache nuit au fonctionnement Jitter-Objectifs | Désactiver, épingler manuellement |
| Fixation manuelle via numactl/cgroups | Le système automatique entre en conflit avec les paramètres fixes Politiques | Désactiver |
| Politiques de mémoire statiques (MPOL_BIND, etc.) | Les migrations n'apportent pas de véritable Avantage | Désactiver |
| Environnement de test et d'analyse | Bonne vue sur le site et Effets | Laisser actif, vérifier les variantes |
Guide des essais et de la validation
Je démarre avec le Balancer activé et je compare les performances locales et distantes Accès via numastat. Ensuite, je désactive la fonction et je répète les mesures à l'identique. J'évalue les différences non seulement en termes de moyennes, mais aussi en termes de Centiles. Les tests de régression réalisés à l'aide de profils de charge issus de la production fournissent les résultats les plus fiables. Ce n'est qu'alors que je prends la décision définitive concernant le choix entre un serveur hôte, une machine virtuelle ou une solution spécifique Service.
Obstacles courants et idées reçues
Une idée fausse très répandue veut que le mode automatique remplace tout Épingler. Ce n'est pas vrai, car les budgets de latence fixes ne tolèrent guère de défauts supplémentaires. Il est tout aussi erroné de supposer que les migrations sont toujours gratuit se produire. Dans le cas des mises en page déjà locales, la surcharge a souvent un effet négatif plutôt que positif. En évitant les idées reçues et en effectuant des mesures précises, on prend des décisions nettement plus Précision du tir.
Limites de l'automatisation et interactions
AutoNUMA a un impact important sur les pages anonymes qu'un processus alloue lui-même. Cependant, tout ne peut pas être migré de manière pertinente. Les pages épinglées (mlock), la mémoire DMA/périphérique, les zones enregistrées DAX ou RDMA restent à leur emplacement d'origine. De même, les pages partagées (par exemple, les bibliothèques fortement partagées ou le cache de pages) n’apportent qu’un bénéfice limité en termes de migration, car plusieurs processus se disputent Modèles d'accès générer. Je tiens également compte des coûts liés à Pages transparentes volumineuses (THP) : leur migration coûte plus cher que celle des pages de 4 KiB et peut entraîner des pics de charge. Ceux qui visent des objectifs stricts en matière de latence combinent souvent THP=never ou madvise avec un équilibrage désactivé et un pinning propre, afin d'éviter toute surprise.
Un autre aspect concerne l'interaction avec le planificateur du processeur. Le planificateur tente de placer les threads là où se trouvent leurs données, tandis que le répartiteur déplace les données là où s'exécutent les threads. Ces deux mécanismes se complètent, mais peuvent, en cas de charge irrégulière, entraîner temporairement oscillations conduire. Dans la pratique, les intervalles de balayage atténuent ces effets ; si l'on constate des profils de charge extrêmement instables, on peut remédier à la situation en allongeant les périodes de balayage ou en recourant à un « thread-pinning » plus stable.
Réglage précis des paramètres de numérisation
Outre le commutateur global, il existe des paramètres du noyau qui me permettent d'ajuster avec précision le niveau d'agressivité du système automatique. Leurs noms exacts peuvent varier légèrement selon la version du noyau, mais leur fonction reste la même :
- kernel.numa_balancing_scan_delay_ms : délai d'attente après un démarrage, un « fork » ou un « exec » avant le début du premier balayage.
- kernel.numa_balancing_scan_period_min_ms / _max_ms : limites inférieure et supérieure de la fréquence de balayage par plage d'adresses de processus.
- kernel.numa_balancing_rate_limit_mb : limite maximale par intervalle de temps pour les migrations de pages, afin de préserver la bande passante mémoire.
- kernel.numa_balancing_scan_size_mb : quantité de mémoire marquée par passage de balayage (si disponible).
Par mesure de prudence, dans les configurations où la latence est critique, j'augmente les périodes minimales et maximales et je réduis les limites de débit, plutôt que de désactiver immédiatement le système automatique. Cela offre souvent un bon compromis : moins de « hint faults », moins de migrations, mais une réactivité suffisante face aux erreurs de placement réelles.
Exemples # (temporaires, jusqu'au redémarrage)
sysctl -w kernel.numa_balancing_scan_period_min_ms=60000
sysctl -w kernel.numa_balancing_scan_period_max_ms=240000
sysctl -w kernel.numa_balancing_rate_limit_mb=64
Indicateurs et diagnostic approfondis
Pour prendre des décisions éclairées, je consulte des indicateurs qui mettent directement en évidence le mécanisme à l'œuvre. J'utilise régulièrement trois sources :
- numastat : rapport entre les accès locaux et distants à l'échelle du système et par processus.
- /proc//numa_maps : répartition des pages mémoire d'un processus entre les nœuds, avec des indicateurs tels que « active », « file » et « anon ».
- /proc/vmstat : des compteurs tels que numa_hint_faults, numa_hint_faults_local et numa_pages_migrated indiquent si le balancier fonctionne et s'il Succès a.
# Aperçu par processus
numastat -p
# Vue détaillée : où se trouvent les zones ?
grep -E 'anon|file' /proc//numa_maps | head
# Vue globale de l'activité AutoNUMA au niveau du noyau
grep -E 'numa_(hint_faults|pages_migrated)' /proc/vmstat
Je recherche des tendances dans les résultats : la part des accès locaux augmente-t-elle de manière stable ? Les « hint faults » diminuent-elles parallèlement ? Si c'est le cas, c'est que la mise en page est efficace. Si la part locale reste stable malgré de nombreuses migrations, j’ai plutôt tendance à gaspiller des cycles. Pour les objectifs de latence, je vérifie en outre les 95e et 99e centiles des temps de réponse ; de petits gains en moyenne peuvent être compensés par Jitter être recouvert.
Profils de charge de travail : ce qui fonctionne généralement
L'expérience a permis de dégager des schémas indiquant dans quels cas AutoNUMA est généralement utile et dans quels cas il ne l'est pas :
- Services JVM et serveurs d'applications : ils en tirent souvent profit, à condition qu'aucune stratégie stricte de « thread pinning » ni aucune logique NUMA propre et agressive ne soit active. Certains environnements d'exécution proposent des options NUMA ; lorsque je les utilise de manière stricte, je réduis le fonctionnement automatique ou je le désactive.
- Bases de données relationnelles : en cas de charge variable avec des caches mixtes, le système automatique fonctionne souvent bien. Cependant, si je configure un « pinning » dédié (Worker-to-Node, tampons partagés strictement répartis), je désactive l'équilibrage pour garantir une reproductibilité parfaite.
- Mémoires en mémoire et caches : un ensemble de données actif volumineux et fréquemment utilisé tire profit d'un placement local. Si l'instance fonctionne en mode mono-thread ou est strictement épinglée, j'évite les migrations inutiles en désactivant cette fonctionnalité.
- HPC/MPI et codes scientifiques : il existe généralement des règles claires de placement et de liaison (OpenMP/numactl). Dans ce cas, la prévisibilité prime sur l'automatisme : je désactive l'équilibrage NUMA.
Virtualisation : vNUMA, pinning et migration à chaud
Dans la relation entre l'hôte et l'invité, je tiens compte des deux niveaux :
- Si la topologie vNUMA de l'invité correspond à la topologie NUMA physique de l'hôte, le répartiteur de charge de l'invité peut prendre des décisions pertinentes. En cas de divergence, il en résulte des „ voisinages erronés “ que la fonction AutoNUMA ne peut compenser que de manière limitée.
- Si j'affecte de manière fixe les vCPU aux processeurs hôtes et que j'associe la mémoire de l'invité à des nœuds spécifiques, il s'agit d'une politique explicite : je réduis ou désactive AutoNUMA à ce niveau de la machine virtuelle afin d'éviter les migrations en double.
- Après les migrations en production, j'observe une phase de stabilisation : les « Hint-Faults » augmentent jusqu'à ce qu'un nouvel équilibre s'installe. Pendant cette période, je prévois des marges pour Latence-pointes.
Sur les hôtes de virtualisation très chargés, où les instances démarrent et s’arrêtent et où les cgroups redistribuent la charge, la gestion automatique au niveau de l’hôte reste souvent un avantage net. Pour les machines virtuelles dédiées sensibles aux „ voisins bruyants “, j’isole proprement les ressources et je définis les règles de manière statique.
Valeurs cibles pragmatiques et critères d'acceptation
Je définis d'emblée ce que signifie „ bien “, afin de ne pas passer un temps infini à peaufiner :
- Services généraux : 70–85%. Les accès locaux suffisent souvent lorsque la variance reste faible.
- SLA de latence : objectif > 90% en local, limites maximales clairement définies pour le taux de défaillance cachée et 99e centile stable.
- Lourd en bande passante : les migrations ne doivent pas saturer les canaux de stockage – adapter les limites de débit et les périodes en conséquence.
Je consigne ces seuils et j'analyse les tests A/B sur plusieurs phases de charge. Je ne prends de décision que lorsque les résultats sont reproductibles.
Liste de contrôle de dépannage
- Pics de latence soudains : vérifier s’il existe une corrélation entre les migrations THP et les pics dans « numa_hint_faults ». Mesure corrective : augmenter la durée des analyses, régler THP sur « madvise/never » et, si nécessaire, désactiver « Balance ».
- Peu d'effet malgré l'activation : les threads sont-ils fortement épinglés ou existe-t-il des politiques de mémoire fixes ? Dans ce cas, le système automatique entre en conflit avec les paramètres définis.
- Rythme de migration élevé, mais néanmoins de nombreux accès à distance : vérifier la limite de débit et l'augmenter ; sinon, stabiliser la charge de travail (épinglage de threads, maintien de la chaleur des caches).
- Valeurs de mesure ambiguës : utilisez la vue par processus avec `numastat -p` et `/proc//numa_maps`, et ne vous fiez pas uniquement aux valeurs globales du système.
Des détails souvent négligés
- Charges de travail fortement dépendantes du cache de pages : AutoNUMA agit principalement sur les pages anonymes. Ceux dont le travail est principalement limité par les E/S ne doivent pas s'attendre à des miracles grâce à l'équilibrage.
- Cgroups et cpusets : le fichier cpuset.mems limite les nœuds auxquels un groupe est autorisé à accéder. Il s'agit d'un cadre rigide dans lequel opère le système automatique.
- Connexion à chaud de la mémoire / mise hors ligne d'un nœud : les topologies dynamiques modifient les distances ; après toute modification, il est recommandé d'effectuer un nouveau test et, si nécessaire, d'ajuster les paramètres de scan.
En bref
Pour les charges de travail générales du serveur, je laisse le mode automatique activé, car il permet d'obtenir un résultat proche de celui obtenu manuellement Données ce qui entraîne l'activation de cœurs. En temps réel, en HFT, en cas de « pinning » manuel ou de politiques fixes, je les désactive pour éviter la surcharge et la gigue. Pendant les phases de test, je procède de manière itérative : mesurer, décider, recommencer valider. Je privilégie une configuration simple, je documente chaque modification et j’en vérifie l’impact à l’aide d’indicateurs fiables. Je tire ainsi parti des atouts du matériel NUMA, sans Risques à prendre.


