Esta pagina se ve mejor con JavaScript habilitado

Mongodb Vol1 Tunning SO

 ·  🎃 kr0m

En este artículo se describen una serie de recomendaciones a tener en cuenta a la hora de poner en producción un servidor Mongo bajo Linux, se cubren aspectos como el kernel, sistema de ficheros, consideraciones a tener en cuenta con SELinux/GrSec entre otros.

Estas son solo unas consideraciones básicas, por supuesto cada escenario está vinculado a sus propias particularidades.

Kernel
2.6.36 o posterior.

Sistema de ficheros
XFS o Ext4, preferiblemente XFS, Mongo requiere un sistema de ficheros que soporte la llamada fsync() sobre directorios. Algunos sistemas de ficheros exóticos como HGFS o carpetas compartidas de VBox no lo soportan.

Meter la opción atime en la partición donde estén los ficheros de la DB.

El readahead es beneficioso cuando se realizan lecturas sobre zonas continuas del disco, pero mongo no sigue dicho patrón si no que realiza lecturas aleatorias.

blockdev --setra 32 /dev/sda
blockdev --getra /dev/sda
32

Podemos hacerlo en el arranque del SO:

vi /etc/local.d/mongo.start
#! /bin/bash
blockdev --setra 32 /dev/sda
chmod 700 /etc/local.d/readahead.start

Límites del SO
Los parámetros recomendados por mongo son:

-f (file size): unlimited  
-t (cpu time): unlimited  
-v (virtual memory): unlimited  
-n (open files): 64000  
-m (memory size): unlimited  
-u (processes/threads): 64000
vi /etc/security/limits.conf
mongodb        soft    fsize        unlimited
mongodb        hard   fsize        unlimited
mongodb        soft    cpu        unlimited
mongodb        hard   cpu        unlimited
mongodb        soft    as            unlimited
mongodb        hard   as        unlimited
mongodb        soft    nofile          64000
mongodb        hard   nofile         64000
mongodb        soft    nproc        64000
mongodb        hard   nproc        64000

Con este pequeño script podemos comprobar si todo está en regla:

vi mongoLimitsChecker.sh

#! /bin/bash
for process in $@; do
     process_pids=`ps -C $process -o pid --no-headers | cut -d " " -f 2`

     if [ -z $@ ]; then
        echo "[no $process running]"
     else
        for pid in $process_pids; do
              echo "[$process #$pid -- limits]"
              cat /proc/$pid/limits
        done
     fi
done
chmod 700 mongoLimitsChecker.sh

NTP
Especialmente importante para los clusters con sharding.

Transparent Huge Pages
La correspondencia entre memoria virtual y física es llevada a cabo por la MMU de la CPU, este proceso es relativamente lento, para mitigar dicha lentitud se creó una caché de mapeos llamada TLB pero la TLB es de tamaño limitado por lo que las entradas están continuamente cambiando.

Como la TLB es limitada lo que se puede hacer es hacer las páginas de memoria mas grandes de este modo cubrimos mas espacio de memoria física con las mismas entradas en la TLB.

  • Huge pages es apropiado para aplicaciones que accedan a grandes regiones de memoria continua
  • No funciona con aplicaciones que acceden a pequeñas porciones de memoria en distintas posiciones, como es el caso de mongo

Añadimos el deshabilitar las hugepages en el script de arranque:

vi /etc/local.d/mongo.start

#! /bin/bash
blockdev --setra 32 /dev/sda

if [ -d /sys/kernel/mm/transparent_hugepage ]; then
    thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
    thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
    return 0
fi

echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag

re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]; then
    # RHEL 7
    echo 0  > ${thp_path}/khugepaged/defrag
else
    # RHEL 6
    echo 'no' > ${thp_path}/khugepaged/defrag
fi

unset re
unset thp_path
chmod 700 /etc/local.d/mongo.start

NUMA

La arquitectura NUMA fué diseñada para superar los problemas de escalabilidad en arquitecturas SMP, en esta todas las CPUs compiten por el acceso al bus de la memoria RAM provocando de este modo un cuello de botella. NUMA por otra parte propone un bus de acceso a RAM por cada X CPUs, siendo el acceso a esta RAM mas rápido que el acceso a una RAM de otro grupo de CPUs.

Sobre el papel NUMA pinta muy bien pero se sabe que Mongo no funciona correctamente en este tipo de entornos, primero averiguamos si nuestro hardware soporta NUMA:

emerge sys-process/numactl
numactl –hardware

available: 1 nodes (0) --> Solo hay un nodo, NO es NUMA: Intel Xeon CPU E5-1660 v3 @ 3.00GHz
numactl –hardware
available: 2 nodes (0-1) --> Sí es NUMA: AMD Opteron Processor 4386

Para deshabilitarlo:

echo 0 | tee /proc/sys/vm/zone_reclaim_mode
sysctl -w vm.zone_reclaim_mode=0

Arrancamos mongo mediante numactl:

su mongodb -s /bin/bash
cd
screen -S mongo
numactl –interleave=all /usr/bin/mongod –config /etc/mongodb.conf

SELinux
Es problemático: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/#install-rhel-configure-selinux

GrSec
https://jira.mongodb.org/browse/SERVER-12991

V8, the Javascript engine used by mongodb, requires the ability to write executable pages of memory for Just-In-Time (JIT) compilation.
If an operating system has been configured so it’s not possible to write to executable memory regions, V8 cannot function.

Si te ha gustado el artículo puedes invitarme a un RedBull aquí