lunes, 28 de marzo de 2011

El Día en el que Sobraba Memoria (Hugepages)

Disponer de equipos con mucha memoria es una ventaja, pero solo si la sabemos gestionar. Pero antes, un poco de teoría (en caso de error se agradecerán aportaciones):

Entropy ≥ Memory . Creativity ²Los procesos no trabajan directamente con la memoria física, sino que lo hacen con la memoria virtual. Esto supone muchas ventajas (no entraré en detalles) pero también un coste extra de conversión, entre la memoria física y la virtual.

Para la conversión cada proceso dispone de una tabla de conversión, y como lo que contiene son direcciones de pagina, se llama tabla de paginación. En aplicaciones con mucho consumo de memoria, donde además la información cambia constantemente (por ejemplo, una base de datos), el acceso a la tabla de paginación es constante.




Por suerte existe la "Translation Lookaside Buffer", una pequeña cache con parte de la tabla de paginación. El problema es que la TLB es de tamaño fijo, y como normalmente guardamos direcciones de páginas de 4 KBytes; el total de memoria al que nos da acceso la TLB no es muy grande.

¿Qué supone ésto?

Tal y como se puede leer en el blog de Pythian con:
  • "Utilización intermitente y muy alta de la CPU en modo kernel"
  • "Durante los parones, todas las CPUs usaban el modo kernel dejando la base de datos inutilizable. Incluso entrar y lanzar una simple consulta SELECT * from DUAL; se tomaba su tiempo."
¿Cuál es la solución?

Utilizar tamaños mayores de página o Hugepages (el caso más habitual 2 MBytes). Esto supone acceder a una mayor cantidad de memoria con las mismas entradas (PTE) en la tabla de paginación. Reduciendo así el consumo de CPU.

Los pasos a seguir son:
  1. Definir el límite memlock para el usuario del servicio que estamos configurando, con un valor algo menor de la memoria disponible (/etc/sysctl.conf).
  2. Iniciar el servicio que consume la memoria.
  3. Calcular el número de hugepages que queremos utilizar en función de la memoria consumida por nuestro proceso (en el caso de Oracle hay un script en la Nota 401749.1)
  4. Definir el parámetro del kernel vm.nr_hugepages= en el archivo /etc/security/limits.conf
  5. Reiniciar el servidor.
  6. Revisar el valor: $ grep Huge /proc/meminfo
Detalles sobre su uso, especialmente con Oracle:
  • Si las páginas totales son iguales a las libres, nuestro servicio no aprovecha las Hugepages por lo que estamos desperdiciando memoria, mejor desconfigurarlas.
  • No son compatibles con la AMM (Automatic Memory Management) en 11g
  • Hay un bug con Grid Infraestructure 11g, donde no se utiliza el límite memlock tal y como hemos definido: Bug 9251136 "INSTANCE WILL NOT USE HUGEPAGE IF STARTED BY SRVCTL"
También lo puedes leer en prinsepac.

Imagen: Entropy ≥ Memory . Creativity ²

No hay comentarios: