Kernel VM tunings para mejorar rendimiento en Linux



NOTA: Un buen inicio antes de hacer los tunnings de este post para mejorar el rendimiento de tu linux es habilitar las mejoras de las que hablamos acá, una vez aplicadas puedes reforzar con los settings específicos de este post. Cabe destacar que éstos aplican para cualquier distro/sistema que utilice el kernel línux como su núcleo.

Prefacio

Ayer estuvimos todo el día probando (y considerando) la opción de migrar nuestro deployment a docker, el nuevo engine para containers linux (más de eso después). Sin embargo a final de cuentas no resultó algo factible por algunas razones y tras ver esto, simplemente se optó por darle una manita de gato a los servidores del setup actual "ya que estábamos en eso" jaja...

Hoy les hablaré de cómo mejorar el rendimiento de sus equipos y servidores linux con 4 perfiles especializados de VM Tunnings (virtual memory tunnings) para el kernel según el caso, sin embargo cabe destacar que lo primero que hemos de hacer para asegurar la máxima efectividad de dichos tunnings es establecer en nuestros equipos unix limits de grado empresarial como los que nos recomiendan los chicos de 10Gen (MongoDB), Oracle y/o Red Hat. Para aplicar estos ulimits simplemente añadimos el bloque de comandos mostrado a conitunación a nuestro rc.local:

ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000

A algunos les podrán parecer altos estos límites, pero ¡no se preocupen! son necesarios. Además, los settings que estableceremos a continuación asegurarán un óptimo funcionamiento de sus equipos/servidores, evitando condiciones "out of memory" y procesos erráticos entre otras cosas.

Swap y Swappiness

Hace tiempo les comentaba de los problemas de memoria que teníamos en nuestro droplet de 512MB dentro de DigitalOcean por un descuido en la alocación de swap para un VPS que estaba destinado a hacer las tareas que éste realizaba. Aunque la alocación de swap y swappiness (en las medidas adecuadas) son vitales para el correcto funcionamiento de un servidor/equipo linux, éstos no son los únicos settings que nos pueden ayudar a tener las cosas funcionando cual maquinaria de reloj suizo, pero sí son un inicio. Como bien nos lo dice la guía de Red Hat:

swappiness
A value from 0 to 100 which controls the degree to which the system swaps. A high value prioritizes system performance, aggressively swapping processes out of physical memory when they are not active. A low value prioritizes interactivity and avoids swapping processes out of physical memory for as long as possible, which decreases response latency. The default value is 60.

Aquí es recomendable aclarar que, (en desktop) si tienes un equipo con RAM limitada (=< 512MB por ejemplo) es buena idea establecer este parámetro a 90 o 100 y si tienes un equipo con bastante RAM (10 GB en adelante) puedes experimentar reduciéndolo a 10 siempre y cuando estés consciente de que tu RAM no se te ha llegado a saturar de manera notable en el pasado (de lo contrario deberías optar por dejar la opción por defecto). Para todos los que están en medio de los rangos citados, el valor predeterminado de 60 es una opción inteligente.

Ahora bien, este valor va muy de la mano con la cantidad de swap disponible en tu sistema, que se debe ajustar acorde a la siguiente tabla (cortesía de Red Hat):


Dirty ratio & Dirty background ratio

Estos son 2 settings súper importantes, ya que determinan la cantidad de memoria (RAM) que un determinado proceso de paginado puede consumir antes de tener que ser "limpiado" hacia disco duro. Linus Torvalds nos da una excelente explicación de porqué estos parámetros se deberían de mantener bajos siempre; Esta "regla" aplica tanto para servidores como para equipos de escritorio con mucha (256GB) o poca (256MB) RAM. Básicamente, para que se entienda mejor, (según lo establecido en estos parámetros) la memoria de tu sistema se irá llenando poco a poco de pequeños pedazos de data que necesitan ser escritos a disco hasta que se alcance el porcentaje establecido en el dirty_ratio, para cuando entonces pdflush entrará en acción y empezará el "writeout" hasta balancear la "carga en la memoria" a la cantidad establecida en el dirty_background_ratio, liberando así esa parte para cosas más importantes. Los valores adecuados para estos 2 parámetros en todos los casos son:

dirty_ratio=10
dirty_background_ratio=5

Hablaremos sobre cómo establecerlos más adelante.

Overcommit Memmory & Overcommit Ratio

Estos 2 son prácticamente exclusivos de servidores (sobretodo aquellos con menos de 1GB de RAM) y funcionan así: Cuando activamos el overcommit_memory, el sistema impedirá que se llegue a un punto donde se consuma toda la SWAP + la cantidad de RAM establecida en el overcommit_ratio. Ésto evita que el sistema llegue a condiciones "fuera de memoria" por aplicaciones erráticas o procesos duplicados, entre otras cosas. No aplica para escritorio porque en escritorio no hay un control real de lo que se está ejecutando, así que establecer estos parámetros puede llevar a comportamientos no deseados (como por ejemplo una pestaña de Chrome "crasheando" para liberar la memoria establecida en los overcommits de pronto o un proceso determinado no ejecutándose porque éstos parámetros "caparon" el uso de la memoria); En escritorio vale más confiar en la swappiness y los valores de los que ya hablamos anteriormente (a menos que se tenga menos de 1GB de RAM, caso en el que se podría considerar activar estos parámetros también). Más sobre los valores adecuados para los overcommits (según el caso) al final; Cabe destacar que éstos settings van muy de la mano con los parámetros del OOM que veremos a continuación.

Settings del OOM

El Out of Memory Killer es un proceso de rescate en Linux que "sale a la carga" una vez que un proceso errático (o repentino) genera una condición Out of Memory (se come la memoria de pronto). Hay 2 settings especialmente útiles para este proceso (que igual sólo aplican en servidores, en este caso de cualquier tipo) y que nos permitirán evitar condiciones OOM y/o bien, malfuncionamiento/comportamiento errático. Éstos son panic_on_oomoom_kill_allocating_task. El primero (tras activarse) habilitará el comportamiento del OOM Killer haciendo que cuando el sistema se quede sin memoria este proceso pueda rescatarlo de una condición errática matando procesos "truhanes" (erráticos) para balancear la carga. El segundo sólo entrará en acción como failsafe si el primero fallara en su tarea de rescatar el sistema matando la tarea que provocó a final de cuentas la condición out of memory asegurándonos operabilidad en cualquier caso en lugar de un panic. Es importante aclarar que al igual que en el caso pasado, se puede considerar habilitar éstos parámetros en un equipo de escritorio con menos de 1GB de RAM también.

Más sobre los valores adecuados para éstos 2 parámetros (según el caso) al finalizar.

Finalizando...

A continuación les mostraré 4 perfiles distintos de éstos diferentes parámetros según el caso (y cómo aplicarlos) para tener un mejor rendimiento (y uptime) en sus equipos/servidores. Si quieren aprender más sobre lo que hacen estos parámetros (y qué otros existen) no olviden checar este enlace.

NOTA: para aplicar los settings que estableceremos en los siguientes perfiles dentro de nuestros equipos/servidores tenemos que editar como root el archivo /etc/sysctl.conf y poner el bloque del perfil deseado al final de dicho archivo, apagando los equipos optimizados después (y volviéndolos a encender) para hacer un flush real de la memoria y hacer efectivos nuestros nuevos ajustes desde cero.

Perfil 1: VPS pequeño y equipos con memoria limitada (=< 512MB RAM)

# Swappiness & Memory Tunning
vm.swappiness=100
vm.overcommit_memory=2
vm.overcommit_ratio=50
vm.oom_kill_allocating_task=1
vm.dirty_ratio=10
vm.dirty_background_ratio=5

Perfil 2: Servidor físico (>= 1GB RAM)

# Swappiness & Memory Tunning
vm.swappiness=60
vm.panic_on_oom=0
vm.oom_kill_allocating_task=1
vm.dirty_ratio=10
vm.dirty_background_ratio=5

Perfil 3: Equipo de escritorio (< 10GB RAM)

# Swappiness & Memory Tunning
vm.swappiness=60
vm.dirty_ratio=10
vm.dirty_background_ratio=5

Perfil 4: Equipo de escritorio (>=10GB RAM)

# Swappiness & Memory Tunning
vm.swappiness=10
vm.dirty_ratio=10
vm.dirty_background_ratio=5

Prueben los perfiles citados y tras un tiempo de uso dejen su experiencia en los comentarios.