Kernel Linux: Transparent Hugepage Support

A mayor cantidad de memoria RAM disponible, el desempeño general del equipo debería ser mayor. Sin embargo en servidores con grandes cantidades de RAM puede darse la paradoja de que el rendimiento disminuya conforme aumenta la cantidad de RAM, incluso podría llegarse al extremo de que los procesos dejen de ejecutarse porque deben de esperar de forma indefinida hasta conseguir que el kernel le asigne memoria RAM.

¿Como es posible que un servidor con muchos gigas de RAM tenga peor desempeño que otro con muchos menos gigas de RAM? Porque a mayor cantidad de memoria RAM, deben de cachearse mayor número de páginas de memoria. Así, por ejemplo, un servidor con 12GiB de RAM con el tamaño de página por defecto (4KiB), tendría una tabla de paginación con 3.145.728 de páginas. Hugepages permite páginas de mayor tamaño, por defecto 2MiB en Linux x86_64 y x86-PAE, y 4MiB en Linux x86. Así, por ejemplo, un servidor Linux x86_64 con 12GiB de RAM y hugepages tendría una tabla de paginación con solo 6.144 páginas.

Tenga en cuenta que hugepages puede incrementar el uso de RAM

Por tanto hugepages permite tablas de paginación mas reducidas y un menor uso de ciclos de CPU en la gestión de las páginas de memoria. Lo cual redunda en un aumento en el desempeño del servidor. En este tutorial se verá como configurar hugepages.

Tabla de contenidos

1.- Antecedentes
Todos los procesos consumen una determinada cantidad de RAM. Y el sistema operativo debe de gestionar los datos almacenados en RAM por cada proceso. Las CPU x86 y x86_64 trabajan con fragmentos de 4KiB, llamados páginas. Puesto que el espacio de direcciones es virtual, la CPU y el sistema operativo deben de recordar que pagina pertenece a cada proceso y donde se almacena, lo cual consiguen mantenimiento una tabla de paginación por cada proceso. La función de la tabla de paginación es traducir las direcciones de memoria virtual (o lógica) a direcciones de memoria física.


2.- ¿Qué es hugepages?
Al usar paginas de 4KiB, se obtiene una buena relación entra el uso de ciclos de CPU y el consumo de RAM en aplicaciones genéricas. Sin embargo cuando un proceso consume gran cantidad de RAM, el uso de páginas de 4KiB origina que deban de leerse muchas páginas para recuperar los datos almacenados por dicho proceso, lo que provoca un uso excesivo de ciclos de CPU. Así, por ejemplo, si un proceso consume 1GiB de RAM serían necesarios 262.144 páginas (1GiB / 4KiB) y 262.144 ciclos de CPU para poder leer todos los datos almacenados por dicho proceso.

Las hugepages tienen como objetivo minimizar este problema creando páginas de gran tamaño (por defecto 2MiB en x86_64 y x86-PAE, y 4MiB en x86). Así, por ejemplo, en un sistema con un proceso que consuma 1GiB de RAM, y hugepages correctamente configurado, la CPU tan solo debería de leer 512 páginas (1GiB / 2MiB) en lugar de 262.144 paǵinas (1GiB / 4KiB). Por tanto las hugepages permiten aumentar el rendimiento al disminuir los ciclos de CPU necesarios para la paginación; y además disminuye el uso de memoria necesaria para mantener las tablas de paginación, puesto que no es lo mismo el tamaño que ocupa una tabla de paginación que guarda la referencia a 512 páginas que otra que guarda referencia a 262.144 páginas.

Algo que debe tener en cuenta, es que al configurar hugepages en el kernel usted decide si desea que hugepages sea utilizado siempre (CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS) o bajo petición (CONFIG_TRANSPARENT_HUGEPAGE_MADVISE). Si usted está configurando un servidor que realiza un trabajo intensivo con datos (bases de datos, múltiples instancias de maquinas virtuales...) puede configurar el uso de hugepages siempre, aunque corre el riesgo de aumentar el uso de memoria RAM sin garantías de beneficio. En cualquier otro caso, la mejor opción, es configurar hugepages bajo petición, y configurar los programas, que hacen un uso intensivo de RAM, para que usen las hugepages en lugar de las páginas de 4KiB.


3.- Configurar hugepages
3.1.- Añadir soporte para hugepages en el kernel
Deberá de compilar el soporte de hugepages en el kernel, si no esta seguro si su kernel tiene soporte para hugepages puede verificarlo grep -i hugepage /usr/src/linux/.config
agd-server # grep -i hugepage /usr/src/linux/.config
CONFIG_TRANSPARENT_HUGEPAGE=y
# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
En caso de que no tenga soporte para hugepages, puede activarlo en Processor type and features --> Transparent Hugepage Support y Pseudo filesystems --> HugeTLB file system support.
┌────────────────────── Processor type and features ─────────────────────┐
│ Arrow keys navigate the menu.  <Enter> selects submenus --->.          │
│ Highlighted letters are hotkeys.  Pressing <Y> includes, <N> excludes, │
│ <M> modularizes features.  Press <Esc><Esc> to exit, <?> for Help, </> │
│ for Search.  Legend: [*] built-in  [ ] excluded  <M> module  < >       │
│ ┌────^(-)────────────────────────────────────────────────────────────┐ │
│ │    -*- Allow for memory compaction                                 │ │
│ │    -*- Page migration                                              │ │
│ │    [*] Enable KSM for page merging                                 │ │
│ │    (4096) Low address space to protect from user allocation        │ │
│ │    [ ] Enable recovery from hardware memory errors                 │ │
│ │    [*] Transparent Hugepage Support                                │ │
│ │          Transparent Hugepage Support sysfs defaults (madvise) --->│ │
│ │    [*] Enable cleancache driver to cache clean pages if tmem is pre│ │
│ │    [ ] Check for low memory corruption                             │ │
│ │    (64) Amount of low memory, in kilobytes, to reserve for the BIOS│ │
│ └────v(+)────────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────────────┤
│                    <Select>    < Exit >    < Help >                    │
└────────────────────────────────────────────────────────────────────────┘
┌────────────────────────── Pseudo filesystems ──────────────────────────┐
│ Arrow keys navigate the menu.  <Enter> selects submenus --->.          │
│ Highlighted letters are hotkeys.  Pressing <Y> includes, <N> excludes, │
│ <M> modularizes features.  Press <Esc><Esc> to exit, <?> for Help, </> │
│ for Search.  Legend: [*] built-in  [ ] excluded  <M> module  < >       │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │    -*- /proc file system support                                   │ │
│ │    [ ]   /proc/kcore support                                       │ │
│ │    [*] Tmpfs virtual memory file system support (former shm fs)    │ │
│ │    [*]   Tmpfs POSIX Access Control Lists                          │ │
│ │    -*-   Tmpfs extended attributes                                 │ │
│ │    [*] HugeTLB file system support                                 │ │
│ │    < > Userspace-driven configuration filesystem                   │ │
│ │                                                                    │ │
│ │                                                                    │ │
│ │                                                                    │ │
│ └────────────────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────────────┤
│                    <Select>    < Exit >    < Help >                    │
└────────────────────────────────────────────────────────────────────────┘

3.2.- Crear un sistema de archivos virtual hugetlbfs
Primero debe crear un punto de montaje para hugepages:
agd-server # mkdir /mnt/hugepages
A continuación debe editar /etc/fstab y añadir una nueva entrada para montar el sistema de archivos virtual hugetlbfs en el punto de montaje anteriormente creado:
agd-server # echo "" >> /etc/fstab
agd-server # echo "hugetlbfs /mnt/hugepages hugetlbfs defaults 0 0" >> /etc/fstab
Por último debe indicar el número de hugapages que debe contener el sistema de archivos virtual hugetlbfs. Para ello deberá editar el archivo de configuración /etc/sysctl.conf y añadir la variable vm.nr_hugepages = X, donde X es el número de hugepages que desea asignar.

A continuación podrá ver un ejemplo donde se reserva 1GiB de RAM para hugepages, recuerde que el tamaño de hugepage por defecto es de 2MiB (1GiB / 2MiB == 500 paginas):
agd-server # echo "" >> /etc/sysctl.conf
agd-server # echo "# Asignar 500 paginas de 2MiB (1GiB) para HugePageTables" >> /etc/sysctl.conf 
agd-server # echo "vm.nr_hugepages = 500" >> /etc/sysctl.conf
En caso de que desee reservar el uso de esta hugepages para un grupo concreto, puede indicarlo mediante la variable vm.hugetlb_shm_group = GID, donde GID es la ID del grupo que tendrá acceso a las hugepages.

En el ejemplo siguiente, se reservará el uso de la hugepage recien creada al grupo con ID 990, que en el ejemplo se corresponde al grupo hugepages:
agd-server # echo "" >> /etc/sysctl.conf
agd-server # echo "# Restringir el acceso a hugepages al grupo hugepages (GID 990)" >> /etc/sysctl.conf
agd-server # echo "vm.hugetlb_shm_group = 990" >> /etc/sysctl.conf
Tras reiniciar el PC, su sistema, tendrá configurado un bloque de 1GiB de RAM (500 * 2MiB) para hugepages. Recuerde que puede consultar el uso de hugepages en /proc/meminfo; a continuación podrá ver la salida que arroja /proc/meminfo en un sistema configurado con 500 páginas de 2MiB.
agd-server # grep -i huge /proc/meminfo 
AnonHugePages:         0 kB
HugePages_Total:     500
HugePages_Free:      500
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Como puede ver, en el ejemplo anterior, en el sistema no hay ningún programa que este haciendo uso de hugepages, ya que las 500 hugepages están libres. A continuación se mostrará como configurar kvm para que haga uso de hugepages.


4.- Configurar kvm con hugepage
Para que las máquinas virtuales hagan uso de las páginas hugepage, debe modificar el archivo de configuración xml de cada máquina virtual. Los archivos de configuración de las máquinas virtuales se alojan en /etc/libvirt/qemu/. Y deberá de agregar las siguientes etiquetas:
<memoryBacking>
<hugepages/>
</memoryBacking>
Puede agregar dichas etiquetas en cualquier lugar, siempre y cuando este entre las etiquetas <domain type=""></domain>. Aunque para mantener el orden y facilitar la administración posterior, es recomendable que las coloque justo debajo de la etiqueta que indica la cantidad de memoria asignada a la máquina virtual. A continuación podrá ver un ejemplo del lugar propuesto:

  samba-server
  e2f2e004-1327-ed1e-5061-2e7eff2d6f1a
  524288
  524288
  
  
  
  2
  
     ...
     ...
Debe tener en cuenta que deberá modificar los archivos de configuración xml de todas las máquinas virtuales en la que desee usar hugepage. Y, salvo que se traten de máquinas de pruebas que inicie de forma esporádica, es recomendable que active hugepage para todas las maquinas virtuales que use.

También debe de tener en cuenta que cada máquina virtual consume un extra de 16MiB, por lo que la máquina del ejemplo consume 528MiB (264 hugepages) en lugar de los 512MiB (256 hugepages) que tiene asignados. Este hecho deberá tenerlo en cuenta cuando fije el número hugepages que desea crear.


5.- Configurar mysql con hugepage
Para hacer que mysql use hugepages, tan solo debe editar /etc/mysql/my.cnf y añadir la opción large-pages en la sección [mysqld]. A continuación se muestra un ejemplo:
[mysqld]
large-pages
...
...
Recuerde que si usted restringió el acceso a hugepages a un grupo concreto, deberá añadir el usuario mysql al grupo. Siguiendo el ejemplo usado anteriormente en este tutorial, se debería añadir mysql al grupo hugepages.

0 comentarios:

Publicar un comentario en la entrada

Recuerde que puede utilizar algunos códigos HTML como <b>para negrita</b>, <i>para cursiva</i> y <a href="URL">para enlaces</a>.