J'utilise un système Linux qui a beaucoup d'utilisateurs mais parfois un abus se produit; où un utilisateur peut exécuter un seul processus qui utilise plus de 80% de la CPU/mémoire.
Existe-t-il un moyen d'empêcher cela de se produire en limitant la quantité d'utilisation du processeur qu'un processus peut utiliser (à 10% par exemple)? Je connais cpulimit
, mais il applique malheureusement la limite aux processus que je lui demande de limiter (par exemple les processus simples). Donc, ma question est, comment puis-je appliquer la limite à tous les processus en cours d'exécution et les processus qui seront exécutés à l'avenir sans avoir à fournir leur identifiant/chemin par exemple?
Bien que cela puisse être un abus pour la mémoire, ce n'est pas pour le CPU: quand un CPU est inactif, un processus en cours (en "exécutant", je veux dire que le processus n'attend pas d'E/S ou autre) prendra 100% du 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 pour un utilisateur donné, il vous suffit de vous assurer que son shell de connexion est exécuté avec Nice
: les processus enfants hériteront de la valeur Nice
. Cela dépend de la façon dont les utilisateurs se connectent. Voir Prioriser les connexions ssh (Nice) par exemple.
Vous pouvez également configurer des machines virtuelles. En effet, la définition d'une limite par processus n'a pas beaucoup de sens puisque l'utilisateur peut démarrer de nombreux processus, abusant du système. Avec une machine virtuelle, toutes les limites seront globales à la machine virtuelle.
Une autre solution consiste à définir /etc/security/limits.conf
limites; consultez la page de manuel limits.conf (5). Par exemple, vous pouvez définir le temps processeur maximal par connexion et/ou le nombre maximal de processus par connexion. Vous pouvez également définir maxlogins
sur 1 pour chaque utilisateur.
Nice/renice
Nice
est un excellent outil pour des ajustements ponctuels à un système.
Nice COMMAND
cpulimit
cpulimit
si vous avez besoin d'exécuter un travail gourmand en CPU et que le temps CPU disponible est essentiel pour la réactivité d'un système.
cpulimit -l 50 -- COMMAND
groupes de contrôle
cgroups
applique 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
http://manpages.ubuntu.com/manpages/xenial/man1/cpulimit.1.html
Avez-vous regardé les groupes de contrôle? Il y a quelques informations sur les Arch Wiki à leur sujet. Lisez la section sur cpu.shares
, on dirait qu'il fait ce dont vous avez besoin, et ils peuvent fonctionner au niveau de l'utilisateur, vous pouvez donc limiter tous les processus utilisateur à la fois.
Pour mémoire, ce que vous recherchez est ulimit -v
. Notez que ulimit
est hérité par les processus enfants, donc si vous l'appliquez au shell de connexion de l'utilisateur au moment de la connexion, il s'applique à tous ses processus.
Si vos utilisateurs utilisent tous bash
comme shell de connexion, mettez la ligne suivante dans /etc/profile
devrait entraîner une limite stricte de 1 gigaoctet pour tous les processus utilisateur (plus exactement, un million de kilo-octets):
ulimit -vH 1000000
L'option H
s'assure qu'il s'agit d'une limite stricte, c'est-à-dire que l'utilisateur ne peut pas la réinitialiser par la suite. Bien sûr, l'utilisateur peut toujours remplir la mémoire en démarrant suffisamment de processus à la fois.
Pour les autres shells, vous devrez découvrir quels fichiers d'initialisation ils lisent à la place (et quelle autre commande au lieu de ulimit
ils utilisent).
Pour le CPU, ce que vous souhaitez ne semble pas avoir de sens pour moi. Quelle serait l'utilité de laisser 90% du processeur inutilisé lorsqu'un seul processus est en cours d'exécution? Je pense que ce que vous voulez vraiment, c'est Nice
(et peut-être ionice
). Notez que, comme ulimit
, Nice
les valeurs sont héritées par les processus enfants, donc l'appliquer au shell de connexion au moment de la connexion suffit. Je suppose que cela s'applique également à ionice
mais je ne suis pas sûr.
Puisque vous déclarez que cpulimit ne serait pas pratique dans votre cas, je vous suggère de regarder Nice , renice , et tasket , ce qui peut se rapprocher de ce que vous voulez atteindre, bien que l'ensemble de tâches permette de définir l'affinité CPU d'un processus, il peut donc ne pas être immédiatement utile dans votre cas.
Comme vos balises ont centos
, vous pouvez utiliser systemd
.
Par exemple, si vous souhaitez limiter l'utilisateur avec l'ID de 1234
:
Sudo systemctl edit --force user-1234.slice
Tapez ensuite et enregistrez ceci:
[Slice] CPUQuota=10%
La prochaine fois que l'utilisateur se connectera, cela affectera.
Pages de manuel: systemctl
, systemd.slice
, systemd.resource-control
...
Si vous souhaitez limiter les processus qui sont déjà démarrés, vous devrez le faire un par un par PID, mais vous pouvez avoir un script batch pour le faire comme celui ci-dessous:
#!/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, pypdfocr
lance le tesseract
gourmand.
Dans certains cas, votre processeur est également assez bon, vous pouvez simplement utiliser un renice
comme ceci:
watch -n5 'pidof tesseract | xargs -L1 Sudo renice +19'