¿Cómo uso el espacio de intercambio solo para emergencias?

41

Tengo una computadora portátil Debian (Buster) con 8 GB de RAM y 16 GB de intercambio. Estoy ejecutando una tarea muy larga. Esto significa que mi computadora portátil se ha dejado encendida durante los últimos seis días mientras se agita.

Mientras hago esto, periódicamente necesito usar mi computadora portátil como computadora portátil. Esto no debería ser un problema; la tarea de larga duración está vinculada a E / S, trabajando a través de cosas en un disco duro USB y no requiere mucha RAM (<200 MB) o CPU (<4%).

El problema es que cuando vuelvo a mi computadora portátil después de unas horas, será muy lenta y puede tardar 30 minutos en volver a la normalidad. Esto es tan malo que los monitores de fallas señalan que sus aplicaciones respectivas se han congelado (especialmente las ventanas del navegador) y las cosas comienzan a fallar de manera incorrecta.

Mirando en el monitor del sistema, de los 2.5 GB utilizados alrededor de la mitad se cambia a intercambio. He confirmado que este es el problema al eliminar el espacio de intercambio ( swapoff /dev/sda8). Si lo dejo sin espacio de intercambio, vuelve a la vida casi al instante, incluso después de 24 horas. Con el intercambio, es prácticamente un ladrillo durante los primeros cinco minutos que se han dejado solo seis horas. He confirmado que el uso de memoria nunca excede los 3 GB, incluso mientras estoy fuera.

Intenté reducir el intercambio ( ver también: Wikipedia ) a valores de 10y 0, pero el problema aún persiste. Parece que después de un día de inactividad, el núcleo cree que toda la GUI ya no es necesaria y la borra de la RAM (la cambia al disco). La tarea de larga duración es leer a través de un gran árbol de archivos y leer cada archivo. Por lo tanto, es posible que el núcleo se confunda al pensar que el almacenamiento en caché ayudaría. Pero en un solo barrido de un USB HD de 2 TB con ~ 1 mil millones de nombres de archivo, un GB de RAM adicional no ayudará mucho al rendimiento. Esta es una computadora portátil barata con un disco duro lento. Simplemente no puede volver a cargar datos en la RAM lo suficientemente rápido.

¿Cómo puedo decirle a Linux que solo use espacio de intercambio en una emergencia? No quiero correr sin intercambio. Si sucede algo inesperado, y el sistema operativo de repente necesita unos pocos GB adicionales, entonces no quiero que se eliminen las tareas y preferiría comenzar a usar el intercambio. Pero por el momento, si dejo el intercambio habilitado, mi computadora portátil simplemente no se puede usar cuando la necesito.

La definición precisa de una "emergencia" podría ser un tema de debate. Pero para aclarar lo que quiero decir: una emergencia sería donde se deja el sistema sin otra opción que intercambiar o matar procesos.


¿Qué es una emergencia? - ¿Realmente tienes que preguntar? ... ¡Espero que nunca te encuentres en un edificio en llamas!

No es posible para mí definir todo lo que podría constituir una emergencia en esta pregunta. Pero, por ejemplo, una emergencia podría ser cuando el núcleo está tan forzado para la memoria que ha comenzado a matar procesos con el OOM Killer . Una emergencia NO es cuando el núcleo cree que puede mejorar el rendimiento mediante el intercambio.


Edición final: he aceptado una respuesta que hace exactamente lo que pedí a nivel del sistema operativo. Los futuros lectores también deben tomar nota de las respuestas que ofrecen soluciones a nivel de aplicación.

Philip Couling
fuente
11
Defina "emergencia" y diga algo acerca de cómo esto es diferente de cualquier situación ordinaria cuando se utilizaría el intercambio.
Kusalananda
44
Quería saber si de alguna manera querías definir un tipo especial de "evento de emergencia" fuera de los límites que permitiría al kernel usar swap, pero ese intercambio de otra manera no se usaría. La memoria de paginación de AFAIK es algo que es lento y solo se hace "en emergencias" de todos modos, y lo de "intercambio" es lo único que puede usar para ajustar este comportamiento (pero no soy un usuario de Linux).
Kusalananda
2
No, eso no es correcto. No solo se hace en emergencias. Al menos, pensé que mi pregunta dejaba en claro que solo había usado 3GB de 8GB ... Eso no es una emergencia, pero el kernel se está intercambiando de todos modos. Le sugiero que lea sobre swappiness y temas relacionados. Hay bastante discusión sobre las diversas razones para el intercambio. Es plausible que esté pidiendo un concepto que no existe en el núcleo, pero mis razones para pedirlo están razonablemente bien justificadas ...
Philip Couling
44
Reconozco que el consejo siempre ha sido "nunca ejecutar sin intercambio". Pero los tamaños de memoria tienen velocidades de lectura / escritura escaladas en el disco duro (HDD no SSD), lo que significa que el intercambio es cada vez una mala idea. Parece que algunos creen que el intercambio de 8GB RAM + 8GB realizará un intercambio de 16GB RAM + 0. Si realmente lo hace, algo está muy mal con el kernel de Linux.
Philip Couling
77
@Philip Couling: No, el punto es que 16 GB de RAM + 16 GB de intercambio superarán a 16 GB y 0 de intercambio, especialmente cuando su código necesita 17 GB de memoria :-)
jamesqf

Respuestas:

11

Tener un intercambio tan grande hoy en día suele ser una mala idea. Cuando el sistema operativo cambió solo unos pocos GB de memoria para intercambiar, su sistema ya se había arrastrado hasta la muerte (como lo que vio)

Es mejor usarlo zramcon una pequeña partición de intercambio de respaldo . Muchos sistemas operativos como ChromeOS, Android y varias distribuciones de Linux han habilitado zram de forma predeterminada durante años, especialmente para sistemas con menos RAM. Es mucho más rápido que intercambiar en HDD y puede sentir claramente la capacidad de respuesta del sistema en este caso. Menos en un SSD, pero de acuerdo con los resultados de referencia aquí todavía parece más rápido incluso con el algoritmo lzo predeterminado. Puede cambiar a lz4 para obtener un rendimiento aún mejor con un poco menos de relación de compresión. Su velocidad de decodificación es casi 5 veces más rápida que lzo según el punto de referencia oficial

También hay zswapaunque nunca lo he usado. Probablemente valga la pena probar y comparar cuál es mejor para sus casos de uso

Después de eso, otra sugerencia es reducir la prioridad de esos procesos vinculados a IO y posiblemente dejar un terminal ejecutándose con mayor prioridad para que pueda ejecutar comandos en él de inmediato, incluso cuando el sistema tiene una carga alta

Otras lecturas

phuclv
fuente
Solo para que lo entienda, ¿está diciendo que puedo crear un zramdispositivo de bloqueo, usarlo como intercambio, con un intercambio de menor prioridad como la partición del HDD?
Philip Couling
@PhilipCouling si está usando HDD, entonces sí, definitivamente debería usar un zram o soluciones similares. La prioridad del intercambio debe ser menor que zram, de modo que Linux intente usar el zram primero, y luego considerará el intercambio. Si usa Ubuntu, entonces el paquete zram-config ya se ocupa de la configuración de prioridad para usted
phuclv
3
Estoy aceptando esta respuesta porque parece hacer exactamente lo que he pedido. Si todavía tengo mi intercambio de 16GB habilitado con una prioridad reducida, entonces el núcleo solo lo usará cuando se haya agotado zswap. IE: "en caso de emergencia". Tenga en cuenta que en debian-buster es muy fácil de configurar, simplemente instalando las herramientas zram.
Philip Couling
25

Una solución es asegurarse de que el controlador de cgroup de memoria esté habilitado (creo que está configurado de manera predeterminada incluso en los núcleos medio recientes, de lo contrario deberá agregarlo cgroup_enable=memorya la línea de comando del núcleo). Luego puede ejecutar su tarea intensiva de E / S en un cgroup con un límite de memoria, que también limita la cantidad de caché que puede consumir.

Si está utilizando systemd, puede configurar +MemoryAccounting=yesy MemoryHigh/ MemoryMaxo MemoryLimit(depende de si está utilizando cgroup v1 o v2) en la unidad, o un segmento que lo contenga. Si es un segmento, puede usarlo systemd-runpara ejecutar el programa en el segmento.

Ejemplo completo de uno de mis sistemas para ejecutar Firefox con un límite de memoria. Tenga en cuenta que esto usa cgroups v2 y está configurado como mi usuario, no como root (una de las ventajas de v2 sobre v1 es que delegar esto en no root es seguro, por lo que systemd lo hace).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

Encontré que para que el usuario trabajara tenía que usar un segmento. El sistema uno funciona simplemente colocando las opciones en el archivo de servicio (o utilizando systemctl set-propertyel servicio).

Aquí hay un servicio de ejemplo (usando cgroup v1), tenga en cuenta las dos últimas líneas. Esto es parte de la instancia del sistema (pid = 1).

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

La documentación está adentro systemd.resource-control(5).

derobert
fuente
1
¿No puedes hacer algo comparable y portátil simplemente usando ulimit?
Old Pro
1
@OldPro no realmente. Primero, no hay un límite de AFAIK en el uso de memoria total, incluida la memoria caché de página (que es el uso que se está volviendo excesivo aquí). En segundo lugar, ulimit for memory es por proceso, los cgroups funcionan incluso si la tarea de larga duración se bifurca.
derobert
Pensé que la razón por la cual la contabilidad de memoria está habilitada por defecto en los sistemas más nuevos se debe a un cambio en la systemdversión 238 .
sourcejedi
1
@sourcejedi que es relativamente reciente. Cuando se introdujo el controlador de memoria por primera vez, solo tenerlo disponible (ni siquiera en uso) tenía un costo de rendimiento lo suficientemente grande como para que algunas distribuciones al menos lo deshabilitaran de manera predeterminada y tuvo que pasar ese argumento de línea de comando del núcleo para habilitarlo. Los problemas de rendimiento se solucionaron, por lo que eso cambió, y más recientemente systemd también lo activa por defecto.
derobert
14

Parece que después de un día de inactividad, el núcleo cree que ya no se necesita la GUI completa y la borra de la RAM (la cambia al disco).

El núcleo está haciendo The Right Thing ™ creyéndolo. ¿Por qué mantendría 1 memoria no utilizada en la RAM y esencialmente la desperdiciaría en lugar de usarla como caché o algo así?

No creo que el kernel de Linux intercambie páginas de forma gratuita o anticipada, por lo que si lo hace, debe ser almacenar algo más en la RAM, mejorando así el rendimiento de su tarea de larga ejecución, o al menos con este objetivo.

Si sabe cuándo tendrá que reutilizar su computadora portátil con anticipación, puede usar el atcomando (o crontab) para programar una limpieza de intercambio ( swapoff -a;swapon -a).

Como limpiar el intercambio puede ser excesivo e incluso activar el asesino OOM si, por alguna razón, no todo encaja en la RAM, es posible que "desemplace" 2 todo lo relacionado con las aplicaciones en ejecución que desea revivir.

Una forma de hacerlo sería adjuntar un depurador como gdba cada uno de los procesos afectados y desencadenar una generación de volcado de núcleo:

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

Como escribió, su aplicación de larga ejecución no está reutilizando los datos que lee después del paso inicial, por lo que se encuentra en un caso específico donde el almacenamiento en caché a largo plazo no es útil. Luego, pasar por alto el caché usando E / S directa como lo sugiere Will Crawford debería ser una buena solución.

Alternativamente, puede limpiar regularmente el caché del archivo haciendo eco 1o 3al /proc/sys/vm/drop_cachespseudoarchivo antes de que el sistema operativo considere que es una buena idea intercambiar las aplicaciones y el entorno de la GUI.

Consulte ¿Cómo vaciar los búferes y la memoria caché en un sistema Linux? para detalles.

1 Sin usar en el sentido: ya no se usa activamente desde un período significativo de tiempo, la memoria sigue siendo relevante para sus propietarios.
2 Vuelva a colocar en las páginas RAM almacenadas en el área de intercambio.

jlliagre
fuente
2
Gracias por pensar en las posibles causas. He agregado un poco a la pregunta, ya que podría ser relevante. Me pregunto si hay una manera de reducir la prioridad del almacenamiento en caché en la memoria de la aplicación.
Philip Couling
55
"No creo que el kernel de Linux esté intercambiando páginas de forma gratuita o anticipada, así que si lo hace, eso debe ser almacenar algo más en la RAM, mejorando así el rendimiento". - Creo que esta redacción es un poco ambigua. El núcleo definitivamente escribirá páginas para intercambiar, siempre que tenga la oportunidad (por ejemplo, hay poca E / S de disco). Sin embargo, no los eliminará de la RAM. De esa manera, tienes lo mejor de ambos mundos: si necesitas rápidamente esas páginas nuevamente, ya están en la RAM y no hay nada que hacer. Si surge una emergencia (como dice el OP), simplemente necesita liberar esas páginas en la RAM, porque
Jörg W Mittag
3
... ya están en el intercambio. Y es precisamente por eso que no desea utilizar el intercambio "solo en emergencias", porque durante una emergencia, el sistema ya está bajo tensión y lo último que desea es agregar grandes cantidades de E / S de disco a eso.
Jörg W Mittag
2
Lo que hace que se intercambie es probablemente el proceso de larga duración: está accediendo a los archivos en el disco. Esos archivos en la memoria se habrán utilizado más recientemente que la memoria de la GUI.
jpmc26
3
@ JörgWMittag ¿Tiene evidencia de que el kernel de Linux, cuando el uso de E / S es bajo, escribe páginas de forma preventiva en el área de intercambio "por si acaso", es decir, sin liberarlas de la RAM?
jlliagre
10

¿El proceso que está ejecutando es algo que ha creado usted mismo?

Si es así, podría valer la pena modificar su código para abrir los archivos usando la O_DIRECTbandera, que cita la página del manual :

Intente minimizar los efectos de caché de las E / S desde y hacia este archivo. En general, esto degradará el rendimiento, pero es útil en situaciones especiales, como cuando las aplicaciones hacen su propio almacenamiento en caché. La E / S de archivos se realiza directamente a / desde los búferes de espacio de usuario. El indicador O_DIRECT por sí solo hace un esfuerzo para transferir datos sincrónicamente, pero no ofrece las garantías del indicador O_SYNC de que los datos y los metadatos necesarios se transfieren. Para garantizar E / S síncrona, se debe usar O_SYNC además de O_DIRECT. Vea las NOTAS a continuación para mayor discusión.

Will Crawford
fuente
1
Otro similar (pero probablemente más fácil, ya que estoy bastante seguro de que O_DIRECT tiene restricciones de alineación y matará el rendimiento si sus lecturas no son grandes) es una idea ingeniosa para decirle al núcleo que no necesitará esos datos nuevamente, eliminándolos del caché de página. (por teléfono o proporcionaría enlaces, lo siento)
derobert
1
@derobert Por un lado, el nocachecomando es un truco conveniente para hacer esto. (Utiliza LD_PRELOAD para secuestrar algunas llamadas de libc).
sourcejedi
6

Aquí hay una idea, que no he probado yo mismo (y lamento no tener el tiempo en este momento para experimentar con esto).

Suponga que crea una VM pequeña con solo 512 MB de memoria para su proceso en segundo plano. No estoy seguro de si desea que esto tenga algún intercambio, su llamada y apague el intercambio en su sistema host.

X Tian
fuente
3

Elimine el intercambio o disminuya aproximadamente un 20% ( puede variar con los sistemas ), ya que los sistemas operativos recientes ya no usan el intercambio de la misma manera que lo hicieron en los últimos años. Probablemente responde algunas de sus preguntas:

-> redhat.com oficial

parte de la información de Red Hat a continuación,

En el pasado, algunos proveedores de aplicaciones recomendaban intercambiar un tamaño igual a la RAM, o incluso el doble de la RAM. Ahora imaginemos el sistema mencionado anteriormente con 2 GB de RAM y 2 GB de intercambio. Una base de datos en el sistema se configuró por error para un sistema con 5 GB de RAM. Una vez que se agota la memoria física, se utiliza el intercambio. Como el disco de intercambio es mucho más lento que la RAM, el rendimiento disminuye y se produce una sacudida. En este punto, incluso los inicios de sesión en el sistema pueden volverse imposibles. A medida que se escribe más y más memoria, eventualmente tanto la memoria física como la de intercambio se agotan por completo y el asesino de OOM entra en acción, matando uno o más procesos. En nuestro caso, hay bastante intercambio disponible, por lo que el tiempo de bajo rendimiento es largo.

y

https://wiki.debian.org/Swap

parte del enlace de Debian arriba,

Información y consideraciones relacionadas con la cantidad de intercambio a utilizar:

"La cantidad recomendada de espacio de intercambio ha sido tradicionalmente el doble de la memoria del sistema. Esto ha cambiado con el tiempo a una memoria del sistema una vez y media, ambas respuestas son líneas de base decentes, pero cada vez son menos útiles a la pregunta a medida que pasa el tiempo". Hay muchas variables sobre su sistema y el uso previsto que determinarán el intercambio de sistema disponible que querrá tener ".

Puedes probar:

"La mejor manera de desactivar el intercambio en Linux"


Nota personal:


Desde que tengo 6 GB de RAM y en todo mi sistema operativo Linux recientemente. Nunca he visto ninguna indicación de uso de Swap. Decidí que debía apagarlo por espacio (unos pocos gigabytes más) y porque a veces ha ralentizado mi sistema.

Tyþë-Ø
fuente
1
En el pasado, algunos proveedores de aplicaciones recomendaban intercambiar un tamaño igual a la RAM, o incluso el doble de la RAM. Me siento mucho más viejo al ver eso, de alguna manera ... Aunque todavía tengo uno de los discos duros en la barrera de ~ 528MB y también 2.5GB, de alguna manera esa cita, bueno, es algo de hace mucho tiempo ... Sin embargo, una cita interesante y Podría explicar por qué vi problemas similares hace unos años. Creo que utilicé sysctl para solucionarlo, pero no recuerdo exactamente qué configuración si fue así.
Pryftan