Mejores Prácticas para Ajustar el Swappiness y el Comportamiento de Caché en Linux

Ajusta cuidadosamente el swappiness de Linux y el comportamiento de caché VFS, con ejemplos de cargas de trabajo, comandos sysctl y pasos de validación.

Mejores Prácticas para Ajustar el Swappiness y el Comportamiento de Caché en Linux

Linux utilizará la RAM libre. Eso sorprende a las personas la primera vez que ven un servidor con muy poca memoria "libre" en free -h. La mayor parte de esa memoria puede ser caché de páginas, dentries y caché de inodos, no una fuga. La parte difícil es saber cuándo el kernel está haciendo un buen uso de la RAM y cuándo la recuperación de memoria comienza a perjudicar tus aplicaciones.

Dos configuraciones de sysctl a menudo surgen durante el ajuste de memoria de Linux: vm.swappiness y vm.vfs_cache_pressure. Son útiles, pero no son interruptores mágicos de rendimiento. Un valor incorrecto puede ocultar el problema real o trasladar el dolor de una carga de trabajo a otra.

Comprendiendo los Parámetros de Gestión de Memoria de Linux

Linux utiliza heurísticas para decidir qué páginas de memoria recuperar cuando el sistema necesita más RAM libre. Las dos áreas principales controladas por los parámetros del kernel son el intercambio (mover páginas de memoria inactivas al disco) y el almacenamiento en caché (mantener metadatos del sistema de archivos y datos en RAM).

1. vm.swappiness

vm.swappiness dicta la tendencia del kernel a mover procesos fuera de la memoria física y hacia el espacio de intercambio en el disco. Es un valor entre 0 y 100.

  • Valor más alto (por ejemplo, 60, un valor predeterminado común): El kernel está más dispuesto a recuperar memoria anónima y usar el intercambio como parte de la gestión normal de memoria. Esto puede preservar la caché de páginas, pero también puede perjudicar los servicios sensibles a la latencia si las páginas activas son expulsadas.
  • Valor bajo (por ejemplo, 10 o menos): El kernel prefiere recuperar memoria de la caché de páginas antes de comenzar a intercambiar procesos. Esto mantiene las aplicaciones en ejecución en la RAM por más tiempo, mejorando la capacidad de respuesta, pero potencialmente reduciendo el rendimiento de E/S del disco si el sistema necesita constantemente eliminar páginas de caché.
  • Valor de 0: El kernel evita el intercambio tanto como sea razonablemente posible, pero esto no deshabilita el intercambio. Si necesitas deshabilitar el intercambio, usa swapoff y comprende primero el riesgo de falta de memoria.

Aplicación Práctica de vm.swappiness

La configuración óptima depende en gran medida de la carga de trabajo:

Tipo de Carga de Trabajo Rango de swappiness Recomendado Justificación
Servidores de Base de Datos, Computación de Alto Rendimiento (HPC) 1 - 10 A menudo un buen punto de partida cuando la latencia del intercambio es peor que eliminar la caché. Valida con métricas de carga de trabajo reales.
Servidores de Propósito General, Escritorios 30 - 60 Generalmente razonable a menos que tengas evidencia de que el comportamiento del intercambio te está perjudicando.
Sistemas de servicio de archivos o con uso intensivo de caché 60 o más en algunos casos Puede preservar la caché de páginas, pero solo tiene sentido si el intercambio ocasional es aceptable para la carga de trabajo.

Cómo Verificar el Valor Actual:

cat /proc/sys/vm/swappiness

Cómo Cambiar el Valor Temporalmente (hasta el reinicio):

Para establecer swappiness en 10:

sudo sysctl vm.swappiness=10

Cómo Cambiar el Valor Permanentemente:

Edita el archivo /etc/sysctl.conf y agrega o modifica la línea:

# /etc/sysctl.conf
vm.swappiness = 10

Después de guardar, aplica los cambios sin reiniciar usando:

sudo sysctl -p

Para bases de datos con uso intensivo de memoria, 1 a 10 es un punto de partida común. No lo trates como una regla. Una base de datos que ya tiene su propia caché de búfer, como PostgreSQL o MySQL/InnoDB, generalmente se beneficia de evitar el intercambio. Un servidor de archivos puede preferir una caché de páginas más grande. Una VM pequeña con muy poca RAM sufrirá sin importar el número que elijas.

2. vfs_cache_pressure

vfs_cache_pressure controla cuán agresivamente el kernel recupera la memoria utilizada para los metadatos de directorios e inodos (la caché VFS).

  • Este valor varía de 0 a 1000.
  • El valor predeterminado es típicamente 100.

Con un valor de 100, el kernel equilibra la recuperación de la memoria de la caché VFS contra la recuperación de la memoria utilizada por la caché de páginas (datos del disco). Un valor de 100 significa que cuando existe presión de memoria, el kernel intenta recuperar 1 parte de la memoria caché de inodos/dentries por cada 1 parte de la memoria caché de páginas.

Ajustando vfs_cache_pressure

  • Aumentar el Valor (por ejemplo, > 100): Hace que el kernel sea más agresivo al recuperar la memoria de la caché VFS. Esto libera RAM más rápido, pero puede ralentizar las búsquedas posteriores del sistema de archivos, ya que los metadatos deben leerse del disco nuevamente.
  • Disminuir el Valor (por ejemplo, < 100): Hace que el kernel sea más conservador al recuperar la caché VFS. Esto mantiene la información de directorios e inodos en la memoria por más tiempo, acelerando las operaciones repetidas del sistema de archivos.

Cuándo Disminuir vfs_cache_pressure:

Si tu sistema accede con frecuencia a las mismas estructuras de directorios grandes (común en aplicaciones complejas, orquestación de contenedores o configuraciones de red específicas), establecer este valor más bajo (por ejemplo, 50) puede mejorar el rendimiento al mantener los metadatos fácilmente disponibles en la RAM.

Cuándo Aumentar vfs_cache_pressure:

Si tu sistema sufre de presión de memoria general y deseas que el kernel recupere cualquier memoria no utilizada rápidamente, podrías aumentar este valor, aunque esto es menos común que disminuirlo.

Cómo Verificar el Valor Actual:

cat /proc/sys/vm/vfs_cache_pressure

Cómo Cambiar el Valor Permanentemente:

Edita /etc/sysctl.conf:

# /etc/sysctl.conf
vfs_cache_pressure = 50

Aplica los cambios con sudo sysctl -p.

Advertencia: Valores muy bajos de vfs_cache_pressure pueden hacer que el kernel mantenga la caché de directorios e inodos por más tiempo del esperado. Eso puede ayudar a las cargas de trabajo con uso intensivo de metadatos, pero también puede empeorar la presión de memoria para las aplicaciones. Evita valores extremos a menos que hayas medido el efecto.

Escenarios Integrales de Ajuste

Elegir la combinación correcta de estos parámetros optimiza el equilibrio entre la estabilidad de la aplicación y el almacenamiento en caché del sistema de archivos.

Escenario 1: Servidor de Base de Datos (Prioridad de Memoria)

Objetivo: Maximizar la residencia de memoria de la aplicación; minimizar el intercambio a toda costa.

  • vm.swappiness = 5
  • vfs_cache_pressure = 50 (Mantener los datos del directorio en caché hasta cierto punto, pero priorizar la memoria de la aplicación sobre los metadatos VFS si la RAM se vuelve escasa).

Antes de cambiar cualquier cosa, verifica si la base de datos está realmente intercambiando:

free -h
vmstat 1
grep -E 'pswpin|pswpout' /proc/vmstat

Si los contadores de entrada y salida de intercambio están aumentando durante los picos de latencia de consultas, reducir el swappiness puede ayudar. Si el intercambio no se utiliza y la base de datos es lenta, el swappiness no es tu problema. Mira los planes de consulta, la tasa de aciertos del búfer, los puntos de control, la latencia del disco y la presión de conexión.

Escenario 2: Servidor de Alta E/S de Disco (Prioridad de Caché)

Objetivo: Maximizar el rendimiento del disco manteniendo los datos de archivos a los que se accede con frecuencia en la caché de páginas.

  • vm.swappiness = 80 (Permite que el intercambio ocurra antes para liberar RAM para la expansión de la caché del disco).
  • vfs_cache_pressure = 100 (Equilibrio estándar entre la caché de inodos y páginas).

Este es el escenario donde las personas más a menudo ajustan en exceso. Si el servidor lee principalmente los mismos archivos repetidamente, la caché de páginas importa. Pero si el sistema comienza a intercambiar procesos de trabajo activos para preservar la caché, los usuarios pueden ver una latencia peor aunque la caché del sistema de archivos parezca saludable. Observa el tiempo de respuesta de la aplicación, no solo el tamaño de la caché.

Escenario 3: Host de Virtualización o Sistema de Propósito General

Objetivo: Rendimiento estable en múltiples cargas de trabajo.

  • vm.swappiness = 30 (Una configuración moderada que favorece mantener las VMs/procesos activos en la RAM un poco más que el valor predeterminado de 60, pero aún permite un intercambio controlado).
  • vfs_cache_pressure = 100 (El valor predeterminado suele ser suficiente).

Los hosts de virtualización necesitan precaución adicional porque el comportamiento de la memoria del invitado puede engañar el ajuste a nivel de host. El ballooning, la sobreasignación y el intercambio del invitado pueden interactuar. Un host que intercambia memoria del invitado en gran medida puede crear una latencia dolorosa dentro de las VMs incluso cuando cada invitado piensa que su propia carga de trabajo es normal.

Un Flujo de Trabajo de Ajuste Más Seguro

No comiences editando /etc/sysctl.conf. Comienza probando que la configuración es relevante.

  1. Captura una línea base durante la carga normal:

    free -h
    vmstat 1 10
    cat /proc/sys/vm/swappiness
    cat /proc/sys/vm/vfs_cache_pressure
    
  2. Captura los mismos datos durante el período lento. Agrega memoria a nivel de proceso:

    ps -eo pid,comm,rss,vsz,%mem --sort=-rss | head -20
    
  3. Cambia un valor temporalmente:

    sudo sysctl vm.swappiness=10
    
  4. Ejecuta la carga de trabajo el tiempo suficiente para observar el comportamiento. Busca una menor actividad de intercambio, mejor latencia de la aplicación y ninguna nueva ralentización del sistema de archivos.

  5. Haz que el valor sea persistente solo después de que sobreviva a una ventana de prueba realista.

En sistemas que usan /etc/sysctl.d/, un pequeño archivo dedicado suele ser más limpio que agregar a /etc/sysctl.conf:

sudo tee /etc/sysctl.d/90-memory-tuning.conf >/dev/null <<'EOF'
vm.swappiness = 10
vm.vfs_cache_pressure = 100
EOF

sudo sysctl --system

Si tu sistema de gestión de configuración posee las configuraciones de sysctl, coloca el cambio allí. Las ediciones manuales de sysctl en un servidor son fáciles de olvidar y difíciles de reproducir.

Leyendo free -h Sin Entrar en Pánico

Una salida típica de free -h podría mostrar un número pequeño en free y un número grande en buff/cache. Eso es normal. Linux mantiene los datos de archivos utilizados recientemente en la memoria porque la RAM no utilizada no ayuda a nadie.

Concéntrate en available, el uso de intercambio y si la actividad de intercambio está ocurriendo ahora. Un servidor puede tener intercambio asignado de un pico de memoria pasado pero sin actividad de intercambio actual. Eso es menos urgente que un servidor que intercambia constantemente.

Usa:

vmstat 1

Si si y so se mantienen cerca de cero bajo carga normal, el intercambio no está impulsando activamente la latencia en ese momento. Si permanecen distintos de cero mientras las aplicaciones se detienen, la presión de memoria es un sospechoso serio.

Cuándo No Ajustar Estas Configuraciones

Hay varios casos donde cambiar el swappiness o la presión de caché es la primera solución incorrecta.

Si el servidor no tiene intercambio configurado, vm.swappiness tiene poco efecto práctico. Aún puedes ajustarlo para la consistencia de la política, pero no resolverá la presión de memoria por sí mismo.

Si el intercambio existe solo como una pequeña partición de emergencia, la configuración también tiene un margen limitado para ayudar. El kernel puede elegir cuándo usar el intercambio, pero no puede convertir unos pocos cientos de megabytes de espacio de emergencia en un nivel de memoria real. En esa configuración, concéntrate en el riesgo de OOM y los límites del servicio.

Si un proceso tiene una fuga de memoria real, reducir el swappiness retrasa el dolor. La fuga seguirá creciendo. Reiniciar el servicio puede restaurar la capacidad temporalmente, pero la solución duradera es a nivel de aplicación: parchear la fuga, limitar la memoria, reducir la concurrencia o cambiar la carga de trabajo.

Si el disco es lento debido a una unidad defectuosa, estrangulamiento de almacenamiento o un volumen de nube saturado, el ajuste de memoria puede reducir algunas lecturas pero no solucionará la falla de almacenamiento. Verifica iostat, registros del kernel, métricas de volumen de nube y salud SMART/NVMe.

Si el conjunto de trabajo es más grande que la RAM, no hay un valor perfecto de sysctl. Necesitas más memoria, menos concurrencia, cachés más pequeñas, un diseño de datos diferente o una división de la carga de trabajo.

Notas sobre Contenedores y Kubernetes

El ajuste de memoria se vuelve más complicado en contenedores. Un contenedor puede alcanzar su límite de memoria de cgroup incluso mientras el host tiene RAM libre. La configuración de swappiness del host todavía importa, pero el síntoma inmediato puede ser una muerte por OOM dentro de un pod o contenedor.

Verifica las señales de cgroup y del orquestador:

dmesg -T | grep -i 'killed process'
docker stats
kubectl describe pod <nombre-del-pod>

Para Kubernetes, cambiar los sysctls a nivel de nodo debe ser parte de la configuración del grupo de nodos, no una sesión de shell única. También recuerda que algunos sysctls tienen espacio de nombres y otros son a nivel de nodo. vm.swappiness y vm.vfs_cache_pressure son configuraciones a nivel de host en sistemas Linux típicos, por lo que cambiarlos afecta a cada carga de trabajo en ese nodo.


Monitoreo y Validación

Después de aplicar los cambios, el monitoreo continuo es crucial para validar el impacto. Usa herramientas como free, vmstat y paneles de monitoreo de rendimiento del sistema.

Usando vmstat:

Monitorea las columnas si (entrada de intercambio) y so (salida de intercambio). Un sistema saludable con bajo swappiness debe mostrar valores bajos o cero para si y so bajo carga normal.

vmstat 5 10

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----\ r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 123456 102400 5123456    0    0     0     5   40   70  1  1 98  0  0

Si los valores de so permanecen altos después de reducir swappiness, la carga de trabajo probablemente necesita más memoria utilizable o una menor demanda de memoria. Más RAM es una respuesta, pero no la única. También puedes reducir los recuentos de trabajadores, reducir las cachés de la aplicación, ajustar la memoria de la base de datos, corregir fugas o dividir los servicios entre hosts.

Trata vm.swappiness y vm.vfs_cache_pressure como preferencias de carga de trabajo, no como mejoras universales. El camino práctico es aburrido pero confiable: mide el comportamiento actual de intercambio y recuperación, cambia una configuración, prueba bajo carga real y mantén el cambio solo si el comportamiento de la aplicación mejora.