Limitar los procesos para que no excedan más del 10% del uso de la CPU


32

Opero un sistema Linux que tiene muchos usuarios pero a veces ocurre un abuso; donde un usuario puede ejecutar un solo proceso que usa más del 80% de la CPU / Memoria.

Entonces, ¿hay alguna manera de evitar que esto suceda limitando la cantidad de uso de CPU que un proceso puede usar (al 10%, por ejemplo)? Soy consciente de ello cpulimit, pero desafortunadamente aplica el límite a los procesos que le indico que limite (por ejemplo, procesos individuales). Entonces mi pregunta es, ¿cómo puedo aplicar el límite a todos los procesos en ejecución y procesos que se ejecutarán en el futuro sin la necesidad de proporcionar su identificación / ruta, por ejemplo?


¿Tienes problemas de rendimiento? o son solo los números los que te molestan?
ctrl-alt-delor

@richard Problemas de rendimiento, así que por eso estaba tratando de matar / limitar / poner fin a los procesos que parecen estar usando mucha CPU, pero ya lo hice escribiendo un script bash. Esta también es una máquina virtual si eso ayuda
Giovanni Mounir

2
Tenga cuidado con los procesos de eliminación que pueden ser 100% por muy poco tiempo, también procesos del sistema. Considere cpulimitjunto con su script de búsqueda. Tenga una política y recomiende el uso de cpulimit, luego busque más del 10% y luego limite al 5% (por lo que se recomienda a los usuarios que lo usen cpulimit). Además, asegúrese de poder detectar múltiples procesos que sumen más del 10% para un solo usuario.
ctrl-alt-delor

@richard ¡Gracias Richard por todos estos comentarios muy útiles! ¡Me han ayudado mucho! Su sugerencia de uso cpulimites mucho mejor que simplemente matar el proceso, ya que el usuario puede reiniciarlo más adelante (como se señala en uno de sus comentarios). ¡Gracias!
Giovanni Mounir

Respuestas:


20

Si bien puede ser un abuso para la memoria, no lo es para la CPU: cuando una CPU está inactiva, un proceso en ejecución (por "ejecución", quiero decir que el proceso no está esperando E / S u otra cosa) 100% de tiempo de CPU por defecto. Y no hay razón para imponer un límite.

Ahora, puede configurar prioridades gracias a nice. Si desea que se apliquen a todos los procesos para un usuario determinado, solo necesita asegurarse de que su shell de inicio de sesión se ejecute con nice: los procesos secundarios heredarán el nicevalor. Esto depende de cómo los usuarios inicien sesión. Vea Priorizar los inicios de sesión ssh (agradable) por ejemplo.

Alternativamente, puede configurar máquinas virtuales. De hecho, establecer un límite por proceso no tiene mucho sentido ya que el usuario puede iniciar muchos procesos, abusando del sistema. Con una máquina virtual, todos los límites serán globales para la máquina virtual.

Otra solución es establecer /etc/security/limits.conflímites; consulte la página del comando man limit.conf (5). Por ejemplo, puede establecer el tiempo máximo de CPU por inicio de sesión y / o el número máximo de procesos por inicio de sesión. También puede establecerlo maxloginsen 1 para cada usuario.


1
@GiovanniMounir Quise decir: una máquina virtual por usuario.
vinc17

1
Ya veo, pero desafortunadamente esto consumirá recursos y no será realmente útil para mi propósito, ya que los usuarios pueden requerir el uso de algunos paquetes de desarrollo comunes, y no lo instalaré en cada nueva máquina; Creo que es mejor dejarlo así y hacer el monitoreo automáticamente mediante un script bash.
Giovanni Mounir

1
@GiovanniMounir Puede compartir una partición entre varias máquinas virtuales.
vinc17

@GiovanniMounir Puede usar LXC o Docker para reducir la sobrecarga de virtualización a casi cero. Además, "gustar" no es una razón fuerte. Por ejemplo, iría con su solución si está administrando un host PHP compartido porque hacer LXC o máquinas virtuales requerirá reescribir un software con licencia de $ 15 / $ 5 que es excesivo.
Pooyan Khosravi

Entiendo que agradable solo establece la CPU relativa en comparación con otros procesos. Si ningún otro proceso usa CPU, entonces su proceso usará 100% CPU, no se limitará a 10%.
johny por qué el

25

agradable / renice

nice es una gran herramienta para ajustes "únicos" a un sistema.

 nice COMMAND

cpulimit

cpulimit si necesita ejecutar un trabajo intensivo de CPU y tener tiempo libre de CPU es esencial para la capacidad de respuesta de un sistema.

cpulimit -l 50 COMMAND

cgroups

cgroups aplicar límites a un conjunto de procesos, en lugar de a uno solo

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

Recursos

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


55
Para aquellos que buscan establecer un límite estricto en el uso de la CPU, incluso cuando no se está ejecutando ningún otro proceso, mire el cpu.cfs_quota_usparámetro (consulte el manual )
Diego

Los cgroups son más fáciles de usar gracias a las directivas systemd ... crear una unidad ya sea sistema o usuario para ese propósito es la mejor opción
Yves Martin

para un proceso en ejecución ej .:sudo cgclassify -g cpu:cpulimited 2315444
Aquarius Power

1
Entiendo que agradable solo establece la CPU relativa en comparación con otros procesos. Si ningún otro proceso usa CPU, entonces su proceso usará 100% CPU, no se limitará a 10%.
johny por qué el

10

¿Miraste cgroups? Hay alguna información en Arch Wiki sobre ellos. Lea la sección sobre cpu.shares, parece que está haciendo lo que necesita, y pueden operar a nivel de usuario, por lo que puede limitar todos los procesos de usuario a la vez.


Sin embargo, CGroups es el camino a seguir. También ejecuto (muchos) servidores informáticos compartidos y usamos cgroups para limitar la cantidad máxima de núcleos que puede usar una sesión de inicio de sesión completa . De esta manera, si la persona sigue iniciando nuevos procesos, cada uno obtiene una porción más pequeña. Lo mismo para el uso de la memoria. Puede hacer que los usuarios se coloquen automáticamente en un cgroup con pam_cgroups y el servicio cgrulesengd. Puede usar una 'plantilla' en el archivo cgconfig para colocar a cada usuario en su propio cgroup. cgrulesengd actúa como su script, excepto que en lugar de matar procesos, solo se asegura de que cada proceso esté en el cgroup correcto.
jsbillings

Incluso si no usa cgroups para limitar el uso de recursos, puede usarlo para evaluar la cantidad de recursos que usa un individuo, mirando el archivo 'stat' para cada recurso, luego use esa información para su secuencia de comandos de 5 minutos.
jsbillings

3

Para la memoria, lo que estás buscando es ulimit -v. Tenga en cuenta que ulimites heredado por los procesos secundarios, por lo que si lo aplica al shell de inicio de sesión del usuario en el momento del inicio de sesión, se aplica a todos sus procesos.

Si todos sus usuarios usan bashcomo shell de inicio de sesión, poner la siguiente línea /etc/profiledebería hacer que todos los procesos de usuario tengan un límite estricto de 1 gigabyte (más exactamente, un millón de kilobytes):

ulimit -vH 1000000

La opción Hasegura que es un límite estricto, es decir, el usuario no puede volver a configurarlo después. Por supuesto, el usuario aún puede llenar memoria iniciando suficientes procesos a la vez.

Para otros shells, deberá averiguar qué archivos de inicialización leen en su lugar (y qué otro comando en lugar de ulimitusar).

Para la CPU, lo que deseas no parece tener sentido para mí. ¿Cuál sería el uso de dejar el 90% de la CPU sin usar cuando solo se está ejecutando un proceso? Creo que lo que realmente quieres es nice(y posiblemente ionice). Tenga en cuenta que, como ulimit, nicelos procesos secundarios heredan los valores, por lo que es suficiente aplicarlo al shell de inicio de sesión en el momento del inicio de sesión. Supongo que eso también se aplica, ionicepero no estoy seguro.


Gracias por la sugerencia de memoria! ¿Hay alguna posibilidad de que pueda mostrarme un ejemplo para aplicar esto al shell de inicio de sesión del usuario en el momento del inicio de sesión? No estoy realmente seguro de cómo hacer esto. También lo siento por no ser lo suficientemente claro; lo que intento hacer es no permitir que ningún proceso use más del 10% de la CPU. Entonces, ¿crees que niceserá lo suficientemente bueno como para hacer esto? Si es así, ¿crees que puedes mostrarme un ejemplo para lograr esto?
Giovanni Mounir

Todavía no tengo el punto de mantener la CPU 90% inactiva cuando solo se está ejecutando un proceso.
celtschk

1
Si actualmente hay menos de 10 procesos que se ejecutan simultáneamente (y al ejecutar me refiero a que realmente se está ejecutando, no solo esperando la entrada del usuario o la E / S del disco), entonces está prácticamente garantizado que uno de ellos tendrá más del 10% de CPU. De lo contrario, la CPU estaría prácticamente inactiva. Y si acaba de matar cualquier proceso que supere el 10%, estoy seguro de que tendrá muchos usuarios que querrán matarlo . O al menos, tratará de que lo reemplacen por alguien que tenga idea de lo que significan esos números, porque parece que no lo hace.
celtschk

En contraste con el comentario de @celtschk, si hay 11 o más procesos en ejecución (enlazados a la CPU), entonces serán inferiores al 9.09%. Entonces, si soy un usuario de un sistema que prohíbe más del 10% de uso de la CPU, puedo ejecutar 11 o más procesos y esconderme bajo el radar.
ctrl-alt-delor

@richard Tiene razón, tal vez sería mejor si el script resumiera la cantidad total de memoria / CPU utilizada por un usuario, y luego termina todos los procesos de este usuario cuando el porcentaje alcanza una cantidad específica (también lo registraría fuera)
Giovanni Mounir

3

Puesto que usted está indicando que cpulimit no sería práctico en su caso, entonces le sugiero que mire bonita , renice , y taskset , que pueden acercarse a lo que quiere lograr, aunque taskset permite establecer afinidad CPU de un proceso, por lo que podría no ser de ayuda inmediata en su caso.


1
nicey renice? ¡Eso es bueno! He revisado sus páginas de manual, pero todavía no creo que puedan ayudar con esto, ya que todavía tiene que establecer una ID de proceso. Sin embargo, si pudiera darme un ejemplo que involucre estos paquetes para aplicar el límite en todos los procesos en ejecución / procesos futuros, ¡sería increíble!
Giovanni Mounir

1

Como tus etiquetas tienen centos, puedes usar systemd.

Por ejemplo, si desea limitar el usuario con ID de 1234:

sudo systemctl edit --force user-1234.slice

Luego escribe y guarda esto:

[Slice] CPUQuota=10%

La próxima vez que el usuario inicie sesión, afectará.

Las páginas man: systemctl, systemd.slice, systemd.resource-control...


0

Si desea limitar los procesos que ya se iniciaron, deberá hacerlo uno por uno por PID, pero puede tener un script por lotes para hacerlo como el siguiente:

#!/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

En mi caso pypdfocrlanza el codicioso tesseract.

Además, en algunos casos, si su CPU es bastante buena, puede usar una renicecomo esta:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.