¿Qué es vm.min_free_kbytes y cómo ajustarlo?

What Is Vm Min_free_kbytes



¿Qué es vm.min_free_kbytes sysctl sintonizable para el kernel de Linux y en qué valor debería establecerse? Estudiaremos este parámetro y cómo afecta a un sistema Linux en ejecución en este artículo. Probaremos su impacto en la caché de la página del sistema operativo y en mallocs y lo que muestra el comando system free cuando se establece este parámetro. Haremos algunas conjeturas fundamentadas sobre los valores ideales para este ajuste y mostraremos cómo configurar vm.min_free_kbytes de forma permanente para que sobreviva a los reinicios. Entonces vamos.

Cómo funciona vm.min_free_kbytes

Es posible que el sistema necesite asignaciones de memoria para garantizar el funcionamiento adecuado del propio sistema. Si el kernel permite que se asigne toda la memoria, podría tener problemas cuando necesite memoria para las operaciones regulares para mantener el sistema operativo funcionando sin problemas. Es por eso que el kernel proporciona vm.min_free_kbytes ajustables. El ajuste forzará al administrador de memoria del kernel a mantener al menos X cantidad de memoria libre. Aquí está la definición oficial del documentación del kernel de linux : Se utiliza para obligar a la máquina virtual Linux a mantener una cantidad mínima de kilobytes libres. La máquina virtual usa este número para calcular un valor de marca de agua [WMARK_MIN] para cada zona de baja memoria en el sistema. Cada zona de baja memoria obtiene una cantidad de páginas gratuitas reservadas en función de su tamaño. Se necesita una cantidad mínima de memoria para satisfacer las asignaciones de PF_MEMALLOC; si lo configura en menos de 1024 KB, su sistema se romperá sutilmente y será propenso a bloquearse bajo cargas elevadas. Establecer esto demasiado alto hará que su máquina OOM instantáneamente.







Validando vm.min_free_kbytes Works

Para probar que la configuración de min_free_kbytes funciona según lo diseñado, he creado una instancia virtual de Linux con solo 3,75 GB de RAM. Utilice el siguiente comando gratuito para analizar el sistema:



#gratis -metro



Mirando la utilidad de memoria libre anterior usando el indicador -m para tener los valores impresos en MB. La memoria total es de 3,5 a 3,75 GB de memoria. Se utilizan 121 MB de memoria, 3,3 GB de memoria libre y 251 MB en la memoria caché del búfer. Y hay disponibles 3,3 GB de memoria.





Ahora vamos a cambiar el valor de vm.min_free_kbytes y ver cuál es el impacto en la memoria del sistema. Haremos eco del nuevo valor en el sistema de archivos virtual proc para cambiar el valor del parámetro del kernel como se muestra a continuación:

# echo 1500000> / proc / sys / vm / min_free_kbytes
# sysctl vm.min_free_kbytes



Puede ver que el parámetro se cambió a 1,5 GB aproximadamente y entró en vigor. Ahora usemos el gratis comando de nuevo para ver los cambios reconocidos por el sistema.

#gratis -metro

El comando no modifica la memoria libre ni la caché del búfer, pero la cantidad de memoria se muestra como disponible se ha reducido de 3327 a 1222 MB. Lo que es una reducción aproximada del cambio en el parámetro a 1,5 GB como mínimo de memoria libre.

Ahora creemos un archivo de datos de 2GB y luego veamos qué hace la lectura de ese archivo en la memoria caché del búfer con los valores. A continuación, se explica cómo crear un archivo de datos de 2 GB en 2 líneas de script bash. El script generará un archivo aleatorio de 35 MB usando el comando dd y luego lo copiará 70 veces en un nuevo archivo de datos producción:

# dd if = / dev / random of = / root / d1.txt count = 1000000
# para i en `seq 1 70`; echo $ i; cat /root/d1.txt >> / root / archivo_datos; hecho

Leamos el archivo e ignoremos el contenido leyendo y redirigiendo el archivo a / dev / null como se indica a continuación:

#gatoarchivo de datos> /dev/nulo

Ok, ¿qué le ha pasado a la memoria de nuestro sistema con este conjunto de maniobras? Vamos a comprobarlo ahora:

#gratis -metro

Analizando los resultados anteriores. Todavía tenemos 1.8 GB de memoria libre, por lo que el kernel ha protegido una gran parte de la memoria como reservada debido a nuestra configuración min_free_kbytes. La caché del búfer ha utilizado 1691 MB, que es menos que el tamaño total de nuestro archivo de datos, que es de 2,3 GB. Aparentemente todo el archivo de datos no se pudo almacenar en la caché debido a la falta de memoria disponible para usar en la caché del búfer. Podemos validar que el archivo completo no está almacenado en la caché, sino cronometrando los intentos repetidos de leer el archivo. Si estuviera en caché, tardaría una fracción de segundo en leer el archivo. Vamos a intentarlo.

# time cat archivo_de_datos> / dev / null
# time cat archivo_de_datos> / dev / null

La lectura del archivo tomó casi 20 segundos, lo que implica que es casi seguro que no esté todo en caché.

Como una validación final, reduzcamos vm.min_free_kbytes para permitir que la caché de la página tenga más espacio para operar y podemos esperar que la caché funcione y la lectura del archivo sea mucho más rápida.

# echo 67584> / proc / sys / vm / min_free_kbytes
# time cat archivo_de_datos> / dev / null
# time cat archivo_de_datos> / dev / null

Con la memoria adicional disponible para el almacenamiento en caché, el tiempo de lectura del archivo se redujo de 20 segundos antes a .364 segundos con todo en caché.

Tengo curiosidad por hacer otro experimento. ¿Qué sucede con las llamadas malloc para asignar memoria desde un programa en C frente a esta configuración realmente alta de vm.min_free_kbytes? ¿Le fallará al malloc? ¿Morirá el sistema? Primero restablezca la configuración vm.min_free_kbytes al valor realmente alto para reanudar nuestros experimentos:

#echo 1500000 > /por ciento/sys/vm/min_free_kbytes

Veamos nuevamente nuestra memoria libre:

Teóricamente tenemos 1,9 GB libres y 515 MB disponibles. Usemos un programa de prueba de esfuerzo llamado stress-ng para usar algo de memoria y ver dónde fallamos. Usaremos el probador vm e intentaremos asignar 1 GB de memoria. Dado que solo hemos reservado 1,5 GB en un sistema de 3,75 GB, supongo que esto debería funcionar.

# stress-ng --vm 1 --vm-bytes 1G --timeout 60s
estrés: info:[17537]despacho de cerdos:1vm
estrés: info:[17537]asignación de caché: tamaño de caché predeterminado: 46080K
estrés: info:[17537]ejecución exitosa completadaen60.09s(1min,0.09seco)
# stress-ng --vm 2 --vm-bytes 1G --timeout 60s
# stress-ng --vm 3 --vm-bytes 1G --timeout 60s

Intentémoslo de nuevo con más trabajadores, podemos probar con 1, 2, 3, 4 trabajadores y en algún momento debería fallar. En mi prueba pasó con 1 y 2 trabajadores, pero falló con 3 trabajadores.

Restablezcamos vm.min_free_kbytes a un número bajo y veamos si eso nos ayuda a ejecutar 3 factores de estrés de memoria con 1 GB cada uno en un sistema de 3,75 GB.

# echo 67584> / proc / sys / vm / min_free_kbytes
# stress-ng --vm 3 --vm-bytes 1G --timeout 60s

Esta vez funcionó con éxito sin errores, lo intenté dos veces sin problemas. Entonces puedo concluir que hay una diferencia de comportamiento de tener más memoria disponible para malloc, cuando el valor de vm.min_free_kbytes se establece en un valor más bajo.

Configuración predeterminada para vm.min_free_kbytes

El valor predeterminado para la configuración en mi sistema es 67584, que es aproximadamente el 1.8% de la RAM del sistema o 64 MB. Por razones de seguridad en un sistema muy maltratado, tendería a aumentarlo un poco tal vez a 128 MB para permitir más memoria libre reservada, sin embargo, para el uso promedio, el valor predeterminado parece lo suficientemente sensato. La documentación oficial advierte sobre hacer que el valor sea demasiado alto. Establecerlo en 5 o 10% de la RAM del sistema probablemente no sea el uso previsto de la configuración y es demasiado alto.

Configuración de vm.min_free_kbytes para sobrevivir a los reinicios

Para asegurarse de que la configuración pueda sobrevivir a los reinicios y no se restaure a los valores predeterminados al reiniciar, asegúrese de que la configuración de sysctl sea persistente colocando el nuevo valor deseado en el archivo /etc/sysctl.conf.

Conclusión

Hemos visto que el parámetro optimizable del kernel de Linux vm.min_free_kbytes puede modificarse y puede reservar memoria en el sistema para garantizar que el sistema sea más estable, especialmente durante el uso intensivo y las asignaciones de memoria intensas. La configuración predeterminada puede ser demasiado baja, especialmente en sistemas con mucha memoria, y se debe considerar aumentarla con cuidado. Hemos visto que la memoria reservada por este ajuste evita que la caché del sistema operativo use toda la memoria y también evita que algunas operaciones malloc usen toda la memoria también.