MongoDB Tuning Anti-Patterns: cómo el ajuste de la memoria puede solucionar las cosas

Es su día más ocupado del año y el sitio web se detuvo y finalmente se bloqueó… y eso fue todo porque no entendió cómo MongoDB usa la memoria y dejó su sistema abierto a la inestabilidad del clúster, bajo rendimiento y comportamiento impredecible. . Comprender cómo MongoDB usa la memoria y planificar su uso puede ahorrarle muchos dolores de cabeza, lágrimas y dolor. En los últimos 5 años, se me ha pedido con demasiada frecuencia que resuelva problemas que son fáciles de evitar. Permítanos compartir con usted cómo MongoDB usa la memoria y cómo evitar errores potencialmente desastrosos al usar MongoDB.

En la mayoría de las bases de datos, es mejor contar con más datos en caché en la RAM. Lo mismo en MongoDB. Sin embargo, la memoria caché compite con otros procesos que hacen un uso intensivo de la memoria, así como con los del núcleo.

Para acelerar el rendimiento, muchas personas simplemente asignan recursos al problema más visible. Sin embargo, en el caso de MongoDB, a veces asignar más memoria realmente perjudica el rendimiento. ¿Cómo es esto posible? La respuesta corta es que MongoDB se basa tanto en su caché de memoria interna como en el caché del sistema operativo. Los administradores de sistemas, administradores de bases de datos y desarrolladores suelen considerar que la memoria caché del sistema operativo está «sin asignar». Esto significa que roban la memoria del sistema operativo y la asignan internamente a MongoDB. ¿Por qué es esto potencialmente algo malo? Dejame explicar.

Cómo MongoDB usa la memoria para almacenar datos en caché

Cada vez que ejecuta una solicitud, algunas páginas se copian de los archivos en un caché de memoria interna del proceso mongod para su futura reutilización. Algunos de sus datos e índices se pueden almacenar en caché y recuperar muy rápidamente cuando sea necesario. Esto es lo que hace WiredTiger Cache (WTC). El objetivo del WTC es mantener sus páginas más frescas y usar menos tiempo para proporcionar un acceso más rápido a sus datos. Es excelente para mejorar el rendimiento de la base de datos.

De forma predeterminada, un proceso mongod usa hasta el 50% de la RAM disponible para ese caché. Eventualmente, puede cambiar el tamaño del WTC usando el storage.wiredTiger.engineConfig.cacheSizeGB variable de configuración.

Recuerde que los datos están comprimidos en archivos de disco, mientras que el caché mantiene páginas sin comprimir.

A medida que el WTC se acerca a su máximo potencial, pueden ocurrir más desalojos. El desalojo ocurre cuando las páginas solicitadas no se almacenan en caché y mongod tiene que abandonar las páginas existentes para hacer espacio y leer las páginas ingresadas por el sistema de archivos. El algoritmo de recorrido de desalojo hace algunas otras cosas (ordenar la lista de páginas LRU y conciliar las páginas WT), además de marcar las páginas utilizadas más recientemente como disponibles para su reutilización, y todo eso puede causar lentitud en algún momento debido a un uso más intensivo. IO.

Basado en cómo funciona el WTC, uno podría pensar que es una buena idea asignarle incluso el 80% / 90% de la memoria (si está familiarizado con MySQL, es lo mismo que hace cuando configura el Buffer Pool para InnoDB). La mayoría de las veces esto es un error y para entender por qué ahora vemos otra forma en que Mongod usa la memoria.

Cómo MongoDB usa la memoria para el almacenamiento en búfer de archivos

Cambio repentino de tema: hablaremos un poco sobre el sistema operativo. El sistema operativo también almacena en caché los bloques de disco del sistema de archivos de memoria para acelerar su recuperación si se solicitan varias veces. El sistema proporciona esta función, independientemente de la aplicación que utilice, y es realmente beneficiosa cuando una aplicación necesita acceso frecuente al disco. Cuando la operación IO está habilitada, los datos se pueden restaurar leyendo bloques de la memoria en lugar de acceder al disco de verdad. Entonces la aplicación se servirá más rápido. Este tipo de memoria administrada por el sistema operativo se llama en caché, como se ve en /proc/meminfo. También podemos llamarlo «Almacenamiento en búfer de archivos».

Tenga en cuenta que MongoDB se basa completamente en el sistema operativo para el almacenamiento en búfer de archivos.

En un servidor dedicado, donde ejecuta un solo proceso mongod, siempre que use la base de datos, se almacenarán múltiples bloques de disco en la memoria. Finalmente, casi todos los campos «en caché» + «búfer» en la salida de estado de la memoria que se muestra arriba se usarán solo para los bloques de disco solicitados por mongod.

Una cosa importante es que el caché guarda los bloques de disco exactamente como están. Dado que los bloques de disco se comprimen en archivos WT, también se comprimen los bloques de memoria. Debido a la compresión, en realidad puede almacenar muchos de sus datos e índices de MongoDB.

Supongamos que tiene una relación de compresión de 4x, en un búfer de memoria de 10 GB (memoria caché) puede almacenar hasta 40 GB de datos reales. Es mucho más, es gratis.

juntando cosas

La siguiente imagen le ofrece una descripción general del uso de la memoria.

Usando la memoria MongoDB

Supongamos que tenemos una máquina dedicada con 64 GB de RAM y un conjunto de datos de 120 GB. Debido a la compresión, la base de datos utiliza alrededor de 30 GB de almacenamiento, asumiendo una relación de compresión de 4x, lo cual es bastante común.

Sin cambiar nada en la configuración, el WTC utilizará aproximadamente 32 GB para guardar 32 GB de datos sin comprimir. La memoria restante será utilizada en parte por el sistema operativo y otras aplicaciones y decimos que es de 4 GB. La memoria RAM restante es de 28 GB y se utilizará principalmente para almacenar archivos en búfer. En esos 28 GB podemos almacenar casi todo comprimido base de datos. El rendimiento general de MongoDB será excelente porque la mayoría de las veces no se lee desde el disco. Solo 2 GB de datos de archivos comprimidos no se almacenan en File Buffering. O 8GB de 120GB sin compresión como otra forma de verlo. Entonces, cuando hay acceso a una página que no está entre los 32 GB en el WTC en ese momento, el IO probablemente leerá un bloque de disco desde el búfer de archivos en lugar de acceder al disco real. Al menos 10 veces mejor latencia, tal vez 100 veces. Es asombroso.

Mongod múltiple en la misma máquina es malo

Como dije, la gente odia ver esa (aparentemente) memoria no asignada en sus sistemas. No todos con este concepto erróneo aumentan el WTC, a veces ven esto como una oportunidad para agregar otras monedas en la misma caja, para usar esa memoria no utilizada.

Múltiples procesos mongodi quieren que el sistema operativo también almacene en la memoria caché todo el contenido de su disco duro. Puede limitar el tamaño del WTC, pero no puede influir en las solicitudes de disco ni en el uso del búfer de archivos. Esto hace que se utilice menos memoria para el almacenamiento en búfer de archivos para cualquier proceso mongod que active más E/S de disco real. Además, los procesos compiten para acceder a otros recursos, como la CPU.

Otro problema es que muchos procesos mongoles complican la resolución de problemas. No será tan sencillo identificar la causa raíz de cualquier problema. ¿Qué mongod usa más memoria para almacenar en búfer los archivos? ¿La lentitud del otro mongou afecta el desempeño de mi mongou?

La solución de problemas se puede manejar más fácilmente en una máquina dedicada cuando se ejecuta un solo mongod.

Si una de las máquinas se vuelve loca y usa más CPU y tiempo de memoria, todas las máquinas en la máquina se ralentizarán debido a la menor cantidad de recursos disponibles en el sistema.

Al final, nunca implemente más de una máquina en la misma máquina. Eventualmente, puede considerar los contenedores Docker. Ejecutar mongod en un contenedor puede limitar la cantidad de memoria que puede usar. En este caso, calcule cuánta memoria necesita en total para el servidor y cuánta memoria está reservada para cada contenedor para obtener el mejor rendimiento posible para mongod.

No se recomienda tener un WTC muy grande

Aumentar significativamente el WTC, más del 50% por defecto, también es una mala costumbre.

Con una memoria caché más grande, puede almacenar más datos sin comprimir, pero al mismo tiempo, deja algo de memoria para almacenar el archivo en búfer. Más aplicaciones pueden beneficiarse del WTC más grande, pero tener desalojos de mongod podría desencadenar una gran cantidad de acceso real al disco al ralentizar la base de datos.

Por lo tanto, en la mayoría de los casos, no es recomendable aumentar el WTC por encima del 50% predeterminado. El objetivo es ahorrar suficiente espacio almacenando bloques de disco en la memoria. Esto puede ayudarlo a obtener un rendimiento mucho mejor y más estable.

Conclusiones

Cuando piensas en mongod, debes considerarlo como el único proceso que se ejecuta en el universo. Trate de usar la mayor cantidad de memoria posible. Pero hay dos cachés: el caché WT (documentos sin comprimir) y el búfer de archivos (de archivos comprimidos de WiredTiger), y el rendimiento se verá afectado si se mueren de hambre.

Nunca implemente más contenedores en la misma caja o al menos considere contenedores. Para el WTC, recuerde también que la mayoría de las veces el tamaño predeterminado (hasta el 50 % de la RAM) funciona bien.

Percona Distribution for MongoDB es una alternativa de base de datos MongoDB disponible gratuitamente, que le brinda una solución única que combina los mejores y más importantes componentes comerciales de la comunidad de código abierto, diseñada y probada para trabajar en conjunto.

¡Descarga Percona Distribution para MongoDB hoy!

Author: Ing. Luis

A lo largo de conocer Windows y otros sistemas operativos me eh encontrado con diversos tipos de error, ahora brindo soluciones según mi experiencia-

Deja un comentario