Hugetlbfs Linux: Mejorar el rendimiento de aplicaciones de bases de datos MySQL
Aplicaciones que realizan una gran cantidad de accesos a memoria (varios
GBs) pueden obtener mejoras de rendimiento usando páginas grandes
gracias a la traducción reducida Lookaside Buffer (TLB). Hugetlbfs
es una función de administración de memoria que se ofrece en el kernel de
Linux, que es útil para aplicaciones que utilizan un gran espacio de
direcciones virtuales. Es especialmente útil para aplicaciones de bases de datos tales como MySQL, Oracle y otras. Otras aplicaciones que de utilizacion del prefork (subprocesos) tambien pueden beneficiarse de esta funcionalidad (Por ejemplo Apache).
¿Qué es Hugetlbfs?
La traducción
de la CPU Lookaside Buffer (TLB) es un pequeño escondite utilizado para
almacenacenamiento virtual de la información de mapeo físico. Mediante
el uso de la TLB, una traducción se puede realizar sin la referencia en
la página de entrada a la tabla de memoria que asigna la dirección
virtual. Sin embargo, para mantener las traducciones lo más rápido posible, el TLB es generalmente pequeño. No es raro que las solicitudes de grandes cantidades de memoria superior a la capacidad de mapeo de la TLB ocurran. Los
usuarios pueden utilizar el soporte de páginas grandes en el kernel de
Linux, ya sea usando la llamada al sistema mmap o SYSV o
llamadas al sistema de memoria (shmget, shmat).
Por defecto en los sistemas operativos donde su kernel no posee la funcionalidad antes mencionada, las paginas virtuales poseen un espacio de 4 KB. Mientras si se da uso de la funcionalidad dentro del kernel de Linux, se pueden definir espacios considerable de paginas, donde se puede incrementar del por defecto 4KB a 4MB por cada pagina.
¿Cómo se si mi sistema operativo Linux tiene habilitada dicha funcionalidad en el kernel?
Ejecuta el siguiente comando:
$ grep -i huge /proc/meminfo
La salida debe ser algo mas o menos asi:
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
Hugepagesize: 4096 kB
El PAGE_SIZE defecto en Linux, que también se aplica a / dev / shm (POSIX) de memoria compartida es de 4 KB (4096 bytes). Con la introducción del kernel Linux 2.6, el sistema también puede ser configurado para utilizar páginas grandes, que utiliza un tamaño de página de 2 MB (2048 kilobytes). Kernel Huge Pages, a diferencia de estándar de páginas de memoria compartida no son swapable y, por tanto, fijar y reservado en el inicio del sistema.
$ grep -i huge /proc/meminfo
AnonHugePages: 540672 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
El núcleo compilado con hugepage debe mostrar el número de páginas gigantes configuradas en el sistema.
De lo contrario, es necesario recompilar el kernel de Linux con la opción de CONFIG_HUGETLBFS habilitada.
¿Cómo configuro HugeTLBfs?
La característica de hugetlbfs permite a una aplicación a poder utilizar un tamaño de página mucho más grande de lo normal,
de modo que una entrada de TLB solo puede asignar un mayor espacio de direcciones. Las entradas en HugeTLB pueden variar en tamaño.
Por ejemplo, la arquitectura i386 soporta 4K y 4M (2M en modo PAE), tamaños de página, ia64 arquitectura soporta tamaños de varias
páginas 4K, 8K,64K, 256K, 1M, 4M, 16M, 256M y ppc64 apoya 4K y 16M.
Para asignar hugepage, puede definir el número de páginas gigantes mediante
la configuración de valor en /proc/sys/vm/nr_hugepages, escriba:
sysctl -w vm.nr_hugepages=40
(Puede hacerlo de manera mas manual, abriendo el archivo /etc/sysctl y agregando vm.nr_hugepages=40
)
Hecho lo anterior actualizamos:
bash$ sysctl -p
Ahora a verificar si se configuraron las paginas:
bash# grep -i huge /proc/meminfo
HugePages_Total: 40
HugePages_Free: 40
HugePages_Rsvd: 0
Hugepagesize: 2048 kB
Donde:
- HugePages_Total: 40 - El espacio total otorgado al pool de hugepages.
- HugePages_Free: 40 - El espacio total de paginas libres existentes de la pool total.
- HugePages_Rsvd: 0 - El espacio total de las paginas siendo utilizadas por alguna aplicacion.
- Hugepagesize: 2048 kB -
Para conocer cuantas HugePages eres capaz de facilitar en tu sistema operativo, basta con conocer el total de tu ram fisica disponible.
Suponiendo que el total de tu ram fisica es de 4GB y de esos 4GB decides dar uso de 2GB para la hugepages. Recuerda que por defecto
son 4KB por cada pagina que otorga el kernel, por lo que si digamos tu aplicacion requiere consumir 1GB que son 1024MB / 4KB
necesitaria mas o menos 2560 paginas a reservar para si esa aplicacion, ahora si digamos que para esa aplicacion la configuras con
Hugepages digamos que por 1GB use 4MB en vez de 4KB, cuantas paginas necesitas de 4MB para completar 1024MB? 256 paginas.
Se nota la diferencia? en vez de reservarse y leer 2560 paginas con la paginacion por defecto de 4KB, al utilizar Huge para una aplicacion
y asignarle 4MB por paginas, y le otorgar 1GB a esa aplicacion, solo requerira reservar 256 paginas en vez de 2560.
PD: El proposito puede ser beneficioso, pero por otro lado tiene una fuerte desventaja que de la aplicacion no ocupar completamente la
memoria a solicitar, puede ocupar espacio en memoria redundante que podria ser utilizable por otra aplicacion ;) si por ejemplo le asignas
1GB de hugepages a Apache que son 256 paginas de 4MB cada una, y Apache en su totalidad solo da uso de 230 paginas y requiere un extra
de 2MB pero cada pagina es de 4MB entonces Apache toma otra pagina (231) la ocupa completa (4MB) pero en realidad solo utiliza 2MB...
y los otros 2MB quedan inutilizables para otra aplicacion.
Por ende hay que asegurarse del total mas aproximado a utilizar por dicha aplicacion para evitarse esta redundancia.
CONFIGURAR MYSQL PARA UTILIZAR HugeTLBfs
Verificar a que grupo pertenece MySQL:
# id mysql
#
uid=27(mysql) gid=27(mysql) groups=27(mysql)
Editar:
bash$ vi /etc/sysctl.conf
Agregar:
# Cada pagina son 4MB por ende 4*256 = 1024 MB = 1GB
vm.nr_hugepages=256
# Especifica el grupo que se beneficiara del Huge
vm.hugetlb_shm_group=27
# El tamano de segmentos de memoria
kernel.shmmax = 68719476736
# El tamano de memoria compartida
kernel.shmall = 4294967296
Guardar los cambios. Luego editar /etc/my.cnf
[mysqld]
large-pages
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# resto de configuracion.....
Salvar.
Si utilizar un Linux como Redhat, Centos, Ubuntu, etc. editar:
# vi /etc/security/limits.conf
@mysql soft memlock unlimited
@mysql hard memlock unlimited
Guardar cambios, y finalmente:
# /etc/init.d/mysqld restart
Configurar Memoria Compartida (Shared memory)
# getconf PAGE_SIZE
4096
kernel.shmall: Maximum total size of shared memory in pages (normally 4096 bytes)
kernel.shmmax: Maximum size of shared memory segment in bytes
shmall: Defines the total amount of shared memory in bytes that can
be used on the system at one time. The default value for machines with
64-bit architecture is 4294967296; for 32-bit architecture the default
value is 268435456.
shmmax: Defines the maximum shared memory segment allowed by the
kernel, in bytes. The default value on machines with 64-bit architecture
is 68719476736; for 32-bit architecture, the default value is
4294967295. Note, however, that the kernel supports values much larger
than this.