Comprendre l'affinité CPU et définir la priorité des processus avec nice et renice
Utilisez `taskset`, `nice` et `renice` sous Linux pour ajuster l'affinité CPU et la priorité des processus sans affamer les tâches critiques.
Comprendre l'affinité CPU et définir la priorité des processus avec nice et renice
Lorsqu'un hôte Linux semble surchargé, vous pouvez avoir besoin de plus de contrôle que "laisser l'ordonnanceur décider". L'affinité CPU contrôle où un processus peut s'exécuter, tandis que nice et renice influencent la force avec laquelle il rivalise pour le temps CPU.
Ce guide montre comment utiliser taskset, nice et renice avec des exemples pratiques et les compromis à surveiller avant de modifier les charges de travail en production.
Affinité CPU : Lier les processus à des cœurs spécifiques
L'affinité CPU est un mécanisme qui permet au système d'exploitation de lier un processus ou un thread à un CPU spécifique ou à un ensemble de CPUs. Lorsqu'un processus est lié à un cœur CPU, il ne s'exécutera que sur ce cœur. Cela a plusieurs implications sur les performances :
- Réduction de l'invalidation du cache : Les CPUs modernes ont des caches multi-niveaux (L1, L2, L3) qui stockent les données fréquemment consultées. Lorsqu'un processus migre entre différents cœurs CPU, ses données dans le cache du cœur précédent deviennent invalides, et de nouvelles données doivent être récupérées pour le nouveau cœur. Lier un processus à un seul cœur garantit que ses données restent dans le cache de ce cœur, ce qui permet des temps d'accès plus rapides.
- Minimisation des changements de contexte : Lorsque l'ordonnanceur décide d'exécuter un processus différent sur un cœur, l'état du processus actuel est sauvegardé (changement de contexte) et l'état du nouveau processus est chargé. Si un processus se déplace fréquemment entre les cœurs, la surcharge associée à ces changements de contexte peut s'accumuler. L'affinité CPU peut réduire cette surcharge en maintenant un processus sur le même cœur.
- Architectures NUMA : Dans les systèmes à accès mémoire non uniforme (NUMA), les temps d'accès à la mémoire varient en fonction du cœur CPU et de sa proximité avec le contrôleur mémoire. Lier un processus à un cœur spécifique peut également garantir qu'il accède à la mémoire locale, réduisant ainsi la latence.
Comment définir l'affinité CPU
Bien que le noyau Linux gère souvent l'affinité CPU automatiquement, les administrateurs peuvent l'influencer manuellement. L'outil principal pour cela est taskset.
Utilisation de taskset
La commande taskset permet de récupérer ou de définir un masque d'affinité CPU pour un processus en cours d'exécution ou de lancer une nouvelle commande avec une affinité spécifiée.
Syntaxe :
Pour afficher l'affinité CPU d'un processus en cours d'exécution :
taskset -p <PID>Pour définir l'affinité CPU d'un processus en cours d'exécution :
taskset -p <masque> <PID>Le
<masque>est un nombre hexadécimal représentant un masque de bits des CPUs autorisés. Par exemple,0x1(binaire0001) signifie CPU 0,0x2(binaire0010) signifie CPU 1,0x3(binaire0011) signifie CPUs 0 et 1, etc.Pour lancer une nouvelle commande avec une affinité CPU spécifique :
taskset -c <liste_cpus> <commande>La
<liste_cpus>est une liste d'ID de CPUs séparés par des virgules ou des plages (par exemple,0,0-3,1,3).
Exemple :
Supposons que vous souhaitiez exécuter une tâche de calcul mon_programme et la lier au cœur CPU 3 :
taskset -c 3 ./mon_programme
Si mon_programme est déjà en cours d'exécution avec le PID 12345 et que vous souhaitez le restreindre avec un masque d'affinité :
taskset -p 1 12345
Cette commande utilise un masque hexadécimal, donc 1 signifie CPU 0. Pour déplacer le processus vers le CPU 1, utilisez -c avec les numéros de CPU :
taskset -cp 1 12345
Astuce : Vous pouvez déterminer le nombre de CPUs disponibles en utilisant nproc ou en inspectant /proc/cpuinfo.
Avertissement : Définir incorrectement l'affinité CPU peut entraîner une dégradation des performances. Il est préférable de comparer les performances de votre application avec et sans paramètres d'affinité pour confirmer les avantages.
Gestion de la priorité des processus avec nice et renice
Alors que l'affinité CPU dicte où un processus s'exécute, la priorité du processus dicte combien de temps CPU il obtient par rapport aux autres processus. Linux utilise un concept de "niceness" pour contrôler la priorité d'ordonnancement. La valeur de niceness varie de -20 (priorité la plus élevée, le plus de temps CPU) à +19 (priorité la plus basse, le moins de temps CPU). La niceness par défaut pour les processus est 0.
Une valeur de niceness plus élevée signifie que le processus est "plus gentil" envers les autres processus, leur cédant plus de temps CPU. Inversement, une valeur de niceness plus basse signifie que le processus est moins "gentil" et tentera d'obtenir plus de temps CPU.
La commande nice
La commande nice est utilisée pour exécuter un programme avec un niveau de niceness modifié. Elle est généralement utilisée lors du lancement d'un nouveau processus.
Syntaxe :
nice -n <niveau_niceness> <commande>
-n <niveau_niceness>: Spécifie la valeur de niceness (par défaut 10 si non spécifiée).
Exemple :
Pour exécuter ma_tache_arriere_plan avec une faible priorité (valeur de niceness élevée de 15) :
nice -n 15 ma_tache_arriere_plan
Pour exécuter mon_app_critique avec une priorité élevée (valeur de niceness faible de -10) :
nice -n -10 mon_app_critique
Remarque importante : Seul l'utilisateur root peut attribuer une valeur de niceness négative (augmenter la priorité). Les utilisateurs normaux ne peuvent qu'augmenter la valeur de niceness (diminuer la priorité) de leurs propres processus.
La commande renice
La commande renice est utilisée pour modifier le niveau de niceness d'un ou plusieurs processus déjà en cours d'exécution.
Syntaxe :
renice -n <niveau_niceness> -p <PID>
-n <niveau_niceness>: La nouvelle valeur de niceness.-p <PID>: Le(s) ID de processus du/des processus à modifier.
Exemple :
Pour diminuer la priorité (augmenter la niceness) du processus 12345 à 10 :
renice -n 10 -p 12345
Pour augmenter la priorité (diminuer la niceness) du processus 54321 à -5 (nécessite les privilèges root) :
sudo renice -n -5 -p 54321
renice peut également cibler les processus par utilisateur (-u) ou par groupe de processus (-g).
Exemple :
Pour définir tous les processus appartenant à l'utilisateur www-data à une niceness de 5 :
sudo renice -n 5 -u www-data
Astuce : Utilisez top ou htop pour afficher la valeur de niceness (colonne NI) des processus en cours d'exécution et identifier les candidats à un ajustement de priorité.
Avertissement : Donner à un processus une priorité très élevée (valeur de niceness faible) peut affamer d'autres processus et rendre le système non réactif. À utiliser avec prudence, en particulier sur les systèmes de production.
Scénarios pratiques et bonnes pratiques
Scénarios d'affinité CPU :
- Serveurs de bases de données : Lier les processus de base de données à des cœurs spécifiques peut améliorer les performances des requêtes en garantissant que les données restent dans le cache CPU.
- Applications de trading haute fréquence : Celles-ci nécessitent souvent une latence minimale et des performances prévisibles, ce qui rend la liaison CPU cruciale.
- Hôtes de virtualisation : Pour dédier des cœurs spécifiques aux machines virtuelles ou à l'hôte lui-même, améliorant l'isolation et les performances.
Scénarios de priorité de processus :
- Tâches par lots / tâches d'arrière-plan : Elles peuvent être exécutées avec une valeur de niceness élevée (
nice -n 15) afin de ne pas interférer avec les tâches interactives des utilisateurs ou les services critiques. - Applications interactives : Assurer que les applications de bureau ou les shells restent réactifs en empêchant les tâches d'arrière-plan de consommer toutes les ressources CPU.
- Allocation d'urgence des ressources : Dans de rares cas, si un processus système critique a des difficultés, sa priorité peut être temporairement augmentée à l'aide de
renice(en tant que root).
Bonnes pratiques :
- Évaluez d'abord : Mesurez toujours les performances avant et après l'application des changements d'affinité CPU ou de priorité. Les gains ne sont pas toujours garantis et peuvent dépendre de l'application.
- Comprenez votre matériel : Soyez conscient de la topologie de votre CPU (cœurs, sockets, nœuds NUMA) lors de la définition de l'affinité CPU.
- Utilisez
top/htop: Surveillez l'utilisation du CPU, les valeurs de niceness et les états des processus pour identifier les problèmes de performances et tester les modifications. - Privilèges root pour l'augmentation de priorité : N'oubliez que seul root peut diminuer la valeur de niceness (augmenter la priorité). Utilisez ce pouvoir judicieusement.
- Commencez avec modération : Pour les ajustements de priorité, commencez par des valeurs de niceness modérées (par exemple, 5, 10) avant d'aller aux extrêmes (-20 ou +19).
- Tenez compte de la sensibilité NUMA : Pour les systèmes NUMA, des outils comme
numactloffrent un contrôle plus avancé sur la liaison CPU et mémoire.
À retenir
Utilisez l'affinité CPU lorsque le placement est important, comme pour les services sensibles au NUMA ou les tâches par lots isolées. Utilisez nice et renice lorsque le problème est la priorité d'ordonnancement. Commencez par de petits changements, préférez taskset -c pour des listes de CPU lisibles, et évaluez les performances avant de rendre une règle d'optimisation permanente.