Limitation des processus pour qu'ils ne dépassent pas 10% de l'utilisation du processeur

32

J'exploite un système Linux qui compte de nombreux utilisateurs mais parfois un abus. où un utilisateur peut exécuter un processus unique qui utilise plus de 80% de la CPU / mémoire.

Y a-t-il un moyen d'éviter cela en limitant l'utilisation d'un processeur qu'un processus peut utiliser (à 10% par exemple)? Je suis au courant cpulimit, mais malheureusement, la limite est appliquée aux processus que je lui demande de limiter (processus uniques, par exemple). Ma question est donc la suivante: comment puis-je appliquer la limite à tous les processus en cours et aux processus qui seront exécutés à l'avenir sans avoir besoin de fournir leur identifiant / chemin par exemple?

Giovanni Mounir
la source
Vous rencontrez des problèmes de performance? ou est-ce juste les chiffres qui vous dérangent?
ctrl-alt-delor
@richard Des problèmes de performances, c'est pourquoi j'essayais de supprimer / limiter / mettre fin aux processus qui semblent utiliser beaucoup de ressources processeur, mais je l'ai déjà fait en écrivant un script bash. Ceci est également une machine virtuelle si cela peut vous aider
Giovanni Mounir
2
Méfiez-vous des processus d'abattage pouvant atteindre 100% pendant très peu de temps, ainsi que des processus système. Considérez cpulimiten conjonction avec votre script de recherche. Adoptez une stratégie et recommandez l'utilisation de cpulimit, puis recherchez plus de 10%, puis limitez-le à 5% (les utilisateurs sont donc encouragés à l'utiliser cpulimit). Assurez-vous également que vous pouvez détecter plusieurs processus totalisant plus de 10% pour un seul utilisateur.
ctrl-alt-delor
@richard Merci Richard pour tous ces commentaires utiles! Ils m'ont beaucoup aidé! Votre suggestion d'utilisation cpulimitest bien meilleure que de simplement tuer le processus car il peut être redémarré par l'utilisateur ultérieurement (comme indiqué dans l'un de vos commentaires). Merci!
Giovanni Mounir
1
stackoverflow.com/questions/386945/…
Ciro Santilli a annoncé

Réponses:

20

Bien que cela puisse être un abus de mémoire, ce n’est pas le cas de la CPU: quand une CPU est inactive, un processus en cours (par "running", je veux dire que le processus n’attend pas d’E / S ou autre chose) prendra 100% de temps CPU par défaut. Et il n'y a aucune raison d'imposer une limite.

Maintenant, vous pouvez définir des priorités grâce à nice. Si vous souhaitez qu’ils s’appliquent à tous les processus d’un utilisateur donné, vous devez simplement vous assurer que son shell de connexion est exécuté avec nice: les processus enfants hériteront de la nicevaleur. Cela dépend de la manière dont les utilisateurs se connectent. Voir Priorité aux connexions SSH (nice) par exemple.

Vous pouvez également configurer des machines virtuelles. En effet, définir une limite par processus n'a pas beaucoup de sens puisque l'utilisateur peut démarrer plusieurs processus en abusant du système. Avec une machine virtuelle, toutes les limites seront globales pour la machine virtuelle.

Une autre solution consiste à fixer des /etc/security/limits.conflimites. reportez-vous à la page de manuel limits.conf (5). Par exemple, vous pouvez définir le temps CPU maximum par login et / ou le nombre maximum de processus par login. Vous pouvez également définir maxloginssur 1 pour chaque utilisateur.

vinc17
la source
1
@GiovanniMounir Je voulais dire: une machine virtuelle par utilisateur.
vinc17
1
Je vois, mais malheureusement, cela consommera beaucoup de ressources et ne sera pas vraiment utile, car les utilisateurs peuvent avoir besoin de certains packages de développement courants, et je ne l'installerai pas sur chaque nouvelle machine. Je pense qu'il vaut mieux laisser cela ainsi et faire la surveillance automatiquement par un script bash.
Giovanni Mounir
1
@GiovanniMounir Vous pouvez partager une partition entre plusieurs machines virtuelles.
vinc17
@GiovanniMounir Vous pouvez utiliser LXC ou Docker pour réduire le temps système de la virtualisation à près de zéro. Aussi "aimer" n'est pas une raison forte. Par exemple, je choisirais votre solution si vous gérez un hôte PHP partagé, car exécuter des LXC ou des machines virtuelles nécessitera la réécriture d’un logiciel sous licence à 15/5 $, ce qui est excessif.
Pooyan Khosravi
Si j'ai bien compris, nice ne définit que le processeur relatif par rapport aux autres processus. Si aucun autre processus n'utilise le processeur, votre processus utilisera 100% du processeur, mais pas jusqu'à 10%.
johny pourquoi le
25

gentil / renice

nice est un excellent outil pour apporter des modifications ponctuelles à un système.

 nice COMMAND

cpulimit

cpulimit si vous avez besoin d'exécuter un travail gourmand en ressources processeur et qu'il vous est nécessaire de disposer d'un temps processeur suffisant pour la réactivité du système.

cpulimit -l 50 COMMAND

cgroups

cgroups appliquer des limites à un ensemble de processus plutôt qu'à un seul

cgcreate -g cpu:/cpulimited
cgset -r cpu.shares=512 cpulimited
cgexec -g cpu:cpulimited COMMAND_1
cgexec -g cpu:cpulimited COMMAND_2
cgexec -g cpu:cpulimited COMMAND_3

Ressources

http://blog.scoutapp.com/articles/2014/11/04/restricting-process-cpu-usage-using-nice-cpulimit-and-cgroups

RafaSashi
la source
5
Pour ceux qui souhaitent définir une limite stricte d'utilisation du processeur, même lorsqu'aucun autre processus n'est en cours d'exécution, consultez le cpu.cfs_quota_usparamètre (voir le manuel )
Diego
Les cgroups sont plus faciles à utiliser grâce aux directives systemd ... créer une unité, système ou utilisateur, est la meilleure option
Yves Martin
pour un processus en cours d' exécution ex .:sudo cgclassify -g cpu:cpulimited 2315444
Aquarius Puissance
1
Si j'ai bien compris, nice ne définit que le processeur relatif par rapport aux autres processus. Si aucun autre processus n'utilise le processeur, votre processus utilisera 100% du processeur, mais pas jusqu'à 10%.
johny pourquoi le
10

Avez-vous regardé cgroups? Il y a quelques informations sur Arch Wiki à leur sujet. Lisez la section cpu.sharesintitulée «On dirait qu’elle répond à vos besoins et qu’elle peut fonctionner au niveau de l’utilisateur, ce qui vous permet de limiter tous les processus en même temps.

Paul Schyska
la source
CGroups est la voie à suivre, cependant. J'utilise également (plusieurs) serveurs informatiques partagés et nous utilisons des groupes de contrôle pour limiter le nombre maximal de cœurs qu'une session de connexion entière peut utiliser. De cette façon, si la personne continue à démarrer de nouveaux processus, chacun aura une tranche plus petite. Idem pour l'utilisation de la mémoire. Vous pouvez avoir des utilisateurs automatiquement mis dans un groupe de contrôle avec pam_cgroups et le service cgrulesengd. Vous pouvez utiliser un "modèle" dans le fichier cgconfig pour mettre chaque utilisateur dans son propre groupe de contrôle. cgrulesengd agit comme votre script, sauf qu'au lieu de tuer les processus, il s'assure simplement que chaque processus est dans le bon groupe de contrôle.
jsbillings
Même si vous n'utilisez pas de groupes de contrôle pour limiter l'utilisation des ressources, vous pouvez l'utiliser pour évaluer la quantité de ressources qu'un individu utilise en consultant le fichier 'stat' de chaque ressource, puis utilisez ces informations pour votre script de 5 minutes.
jsbillings
3

Pour mémoire, ce que vous recherchez est ulimit -v. Notez que cela ulimitest hérité par les processus enfants. Par conséquent, si vous l'appliquez au shell de connexion de l'utilisateur au moment de la connexion, il s'applique à tous ses processus.

Si tous vos utilisateurs utilisent bash comme shell de connexion, la ligne suivante /etc/profiledevrait entraîner une limite stricte de 1 Go pour tous les processus utilisateur (plus précisément, un million de kilo-octets):

ulimit -vH 1000000

L'option Hgarantit que la limite est stricte, c'est-à-dire que l'utilisateur ne peut pas la configurer par la suite. Bien entendu, l'utilisateur peut toujours remplir sa mémoire en démarrant suffisamment de processus à la fois.

Pour les autres shells, vous devrez trouver quels fichiers d’initialisation ils lisent à la place (et quelle autre commande au lieu de ulimit leur utilisation).

Pour le processeur, ce que vous souhaitez n'a pas de sens pour moi. Quelle serait l'utilisation de laisser 90% de la CPU inutilisée lorsqu'un seul processus est en cours d'exécution? Je pense que ce que vous voulez vraiment est nice(et éventuellement ionice). Notez que, comme ulimit, les nicevaleurs sont héritées par les processus de l' enfant, afin de l' appliquer à l'interpréteur de commandes à temps suffit de connexion. Je suppose que cela s'applique également à, ionicemais je ne suis pas sûr.

celtschk
la source
Merci pour la suggestion de mémoire! Existe-t-il une chance que vous puissiez me montrer un exemple pour l'appliquer au shell de connexion de l'utilisateur au moment de la connexion? Je ne sais pas trop comment faire ça. Je suis également désolé de ne pas être assez clair; ce que j'essaie de faire est de ne permettre à aucun processus d’utiliser plus de 10% de la CPU. Alors pensez-vous que ce nicesera assez gentil de faire cela? Si oui, croyez-vous pouvoir me montrer un exemple pour y parvenir?
Giovanni Mounir
Je ne comprends toujours pas l'intérêt de garder le processeur inactif à 90% lorsqu'un seul processus est en cours d'exécution.
celtschk
1
S'il y a actuellement moins de 10 processus qui s'exécutent simultanément (et par exécution, j'entends vraiment fonctionner, pas seulement attendre l'entrée utilisateur ou l'entrée / la sortie disque), il est pratiquement garanti que l'un d'entre eux aura plus de 10% de CPU. Sinon, le processeur serait pratiquement inactif. Et si vous supprimez tout processus dépassant 10%, je suis sûr que de nombreux utilisateurs voudront vous tuer . Ou du moins, nous essaierons de vous faire remplacer par une personne ayant une idée de la signification de ces chiffres, car vous semblez ne pas le savoir.
celtschk
Contrairement au commentaire de @celtschk, s'il y a au moins 11 processus en cours d'exécution (liés au cpu), leur nombre sera inférieur à 9,09%. Donc, si je suis un utilisateur d'un système qui interdit l'utilisation de plus de 10% de l'unité centrale, je peux exécuter 11 processus ou plus, et me cacher sous le radar.
ctrl-alt-delor
@richard Vous avez raison, il serait peut-être préférable que le script récapitule la quantité totale de mémoire / CPU utilisée par un utilisateur, puis termine tous les processus de cet utilisateur lorsque le pourcentage atteint un montant spécifique (le consignera également out)
Giovanni Mounir
3

Puisque vous dites que cpulimit ne serait pas pratique dans votre cas, je vous suggère donc de regarder nice , renice et taskset , ce qui peut se rapprocher de ce que vous souhaitez atteindre, bien que taskset permette de définir l'affinité de traitement d'un processus. pourrait ne pas être immédiatement utile dans votre cas.

RJ
la source
1
niceet renice? C'est bien! J'ai consulté leurs pages de manuel, mais je ne pense toujours pas qu'ils puissent vous aider car vous devez toujours définir un ID de processus. Si vous pouviez cependant me donner un exemple impliquant ces paquets d'appliquer la limite sur tous les processus en cours / futurs, ce serait génial!
Giovanni Mounir
1

Depuis que vos tags ont centos, vous pouvez utiliser systemd.

Par exemple, si vous souhaitez limiter les utilisateurs avec l'ID suivant 1234:

sudo systemctl edit --force user-1234.slice

Puis tapez et enregistrez ceci:

[Slice] CPUQuota=10%

La prochaine fois que cet utilisateur se connectera, cela affectera.

Man pages: systemctl, systemd.slice, systemd.resource-control...

pile-politiques-sont-trolls
la source
0

Si vous souhaitez limiter les processus déjà démarrés, vous devrez le faire un par un par PID, mais vous pouvez utiliser un script de traitement par lots comme celui-ci:

#!/bin/bash
LIMIT_PIDS=$(pgrep tesseract)   # PIDs in queue replace tesseract with your name
echo $LIMIT_PIDS
for i in $LIMIT_PIDS
do
    cpulimit -p $i -l 10 -z &   # to 10 percent processes
done

Dans mon cas pypdfocrlance le gourmandtesseract .

De plus, dans certains cas, si votre CPU est assez bon, vous pouvez simplement utiliser renicececi:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'
Eduard Florinescu
la source