sistema - ¿Puedo decirle a Linux que no cambie la memoria de un proceso en particular?
qué es swap en un sistema linux (7)
¿Por qué quieres hacer esto?
Si intenta aumentar el rendimiento de esta aplicación, probablemente esté en la senda equivocada. El sistema operativo cambiará un proceso para aumentar la memoria de la memoria caché de disco, incluso si hay memoria RAM libre, el kernel sabe mejor (de hecho, los tipos que escribieron el planificador saben mejor).
Si tiene un proceso que necesita capacidad de respuesta (se intercambia mientras no se utiliza y necesita reiniciarlo rápidamente), entonces puede ser de gran prioridad, mlock o utilizar un kernel en tiempo real podría ayudar.
¿Hay alguna manera de decirle a Linux que no debe cambiar la memoria de un proceso en particular al disco?
Es una aplicación de Java, así que, idealmente, espero una forma de hacerlo desde la línea de comandos.
Soy consciente de que puedes establecer el swappiness global en 0, ¿pero es así?
Como superusuario, puede ''encantarlo'' al nivel de prioridad más alta -20 y esperar que sea suficiente para evitar que se cancele. Por lo general es así. Los números positivos disminuyen la prioridad de programación. Los usuarios normales no pueden mejorar (números negativos)
Excepto en circunstancias extremadamente inusuales, hacer esta pregunta significa que lo está haciendo mal (tm).
En serio, si Linux quiere intercambiar y está tratando de mantener su proceso en la memoria, entonces está poniendo una demanda irrazonable en el sistema operativo. Si su aplicación es tan importante, entonces 1) compre más memoria, 2) elimine otras aplicaciones / daemons de la máquina, o dedique una máquina a su aplicación, y / o 3) invierta en un subsistema de disco realmente rápido. Estos pasos son razonables para una aplicación importante. Si no puedes justificarlos, entonces probablemente no puedas justificar la memoria del cableado ni tampoco matar a otros procesos.
Existe una clase de aplicaciones en la que nunca desea que se intercambien. Una de esas clases es una base de datos. Las bases de datos usarán la memoria como memorias caché y almacenamientos intermedios para sus áreas de disco, y no tiene ningún sentido que alguna vez se pongan a cambiar. La memoria particular puede contener algunos datos relevantes que no se necesitan durante una semana hasta que un día cuando un cliente lo solicita. Sin el almacenamiento en caché / intercambio, la base de datos simplemente encontraría el registro relevante en el disco, que sería bastante rápido; pero con el intercambio, su servicio de repente puede tomar mucho tiempo para responder.
mysqld
incluye código para usar el memlock
llamada del sistema operativo / sistema. En Linux, al menos desde 2.6.9, esta llamada al sistema funcionará para procesos que no sean raíz y que tengan la capacidad CAP_IPC_LOCK
[1] . Al usar memlock()
, el proceso aún debe funcionar dentro de los límites del límite LimitMEMLOCK
. [2] Una de las (pocas) cosas buenas de systemd
es que puede otorgar al proceso mysqld
estas capacidades, sin necesidad de un programa especial. Si también puede establecer los límites como es de esperar con ulimit
. Aquí hay un archivo de override
para mysqld
que realiza los pasos necesarios, incluidos algunos otros que podría necesitar para un proceso como una base de datos:
[Service]
# Prevent mysql from swapping
CapabilityBoundingSet=CAP_IPC_LOCK
# Let mysqld lock all memory to core (don''t swap)
LimitMEMLOCK=-1
# do not kills this process if low on memory
OOMScoreAdjust=-900
# Use higher io scheduling
IOSchedulingClass=realtime
Type=simple
ExecStart=
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS
Nota La comunidad estándar mysql actualmente viene con Type=forking
y agrega --daemonize
en la opción al servicio en la línea ExecStart
. Esto es intrínsecamente menos estable que el método anterior.
ACTUALIZAR No estoy 100% satisfecho con esta solución. Después de varios días de tiempo de ejecución, noté que el proceso todavía tenía enormes cantidades de intercambio. Examinando /proc/XXXX/smaps
, observo lo siguiente:
- ¡El mayor contribuyente de swap es de un segmento stack! 437 MB y fluctuante. Esto presenta problemas obvios de rendimiento. También indica una fuga de memoria basada en pila.
- Hay cero páginas bloqueadas . Esto indica que la opción de
memlock
en MySQL (o Linux) está rota. En este caso, no importaría mucho porque MySQL no puede bloquear la pila.
Puede hacerlo a través de la llamada al sistema mlockall(2) bajo Linux; esto funcionará para todo el proceso, pero lea sobre el argumento que necesita aprobar.
¿De verdad necesitas sacar todo en núcleo? Si se trata de una aplicación java, probablemente bloquearía toda la JVM en el núcleo. No sé de un método de línea de comandos para hacer esto, pero podrías escribir un programa trivial para llamar a fork
, llamar a mlockall
, y luego a exec
.
También puede ver si una de las notificaciones de patrones de acceso en madvise(2) satisface sus necesidades. Aconsejar al subsistema VM sobre una mejor estrategia de búsqueda podría funcionar mejor si es aplicable para usted.
Tenga en cuenta que hace mucho tiempo ahora bajo SunOS, había un mecanismo similar a madvise llamado vadvise(2) .
Si desea cambiar el swappiness para un proceso, agréguelo a un grupo cg y establezca el valor para ese cgroup:
https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227
Usted puede hacer eso por la familia mlock de syscalls. No estoy seguro, sin embargo, si puedes hacerlo para un proceso diferente.