...

Comprender y configurar de forma óptima el parámetro «vm.max_map_count» de Linux para servidores de bases de datos

Te explico cómo vm.max_map_count comprender, medir y ajustar sin riesgos en servidores de bases de datos Linux. Este artículo muestra pasos concretos, valores típicos y controles probados en la práctica para que PostgreSQL, MySQL/MariaDB, Elasticsearch u OpenSearch funcionen correctamente bajo carga.

Puntos centrales

  • Función: Límite máximo de áreas de memoria virtual (VMA) por proceso
  • Relevancia: Bases de datos, sistemas de búsqueda, pilas de Java con numerosas asignaciones
  • Síntomas: „No se puede asignar memoria“, errores de inicio, bloqueos
  • Valores prácticos: de 262 144 a 1 048 576 para grandes cargas de trabajo
  • Procedimiento: Evaluar las necesidades, aumentarlas con un margen de seguridad e integrar el seguimiento

¿Qué significa «vm.max_map_count»?

El parámetro del núcleo determina cuántos Áreas de memoria (VMAs) que un único proceso puede crear como máximo. Cada operación mmap, cada objeto compartido cargado, muchas asignaciones y bloques de memoria compartida aumentan esta cifra. Con ello no limito la cantidad de RAM, sino la Cantidad de las áreas separadas en el espacio de direcciones virtual. Los procesos de gran tamaño pueden utilizar mucha memoria con unas pocas asignaciones grandes, mientras que las cargas de trabajo fragmentadas alcanzan rápidamente el límite debido a las numerosas asignaciones pequeñas. Quien utilice software que consuma mucha memoria debe conocer este límite máximo; de lo contrario, el error no se detectará hasta que se produzca una carga elevada.

Por qué se ven afectados los servidores de bases de datos

Las bases de datos y los servicios de búsqueda se basan en gran medida en mmap, memoria compartida, cachés y numerosas bibliotecas. Las instancias de PostgreSQL con muchas extensiones y conexiones, MySQL/MariaDB con complementos o Elasticsearch/OpenSearch con muchos segmentos de índice generan numerosas VMA. Si el número se acerca al límite, las asignaciones posteriores fallan y el proceso notifica Error de memoria. Es precisamente en esos casos cuando los servicios no se inician, se interrumpen bajo carga o pierden nodos en los clústeres. Evito este tipo de comportamiento determinando de antemano el límite máximo necesario y configurándolo correctamente.

Síntomas y riesgos de una configuración incorrecta

Los signos más frecuentes de un nivel demasiado bajo son Error de inicio a pesar de que haya memoria libre. Servicios como Elasticsearch muestran el mensaje „Cannot allocate memory“, aunque el sistema aún disponga de recursos libres. También se producen interrupciones esporádicas de los procesos en cuanto se necesitan internamente más VMA de las permitidas. Un valor demasiado alto no suele suponer ningún problema, ya que el kernel solo utiliza un poco más Administración necesario para las estructuras vm_area_struct. Esto solo cobra importancia cuando los procesos crean realmente millones de asignaciones, algo que las cargas de trabajo típicas de las bases de datos no suelen alcanzar.

Valores extraídos de la práctica y su interpretación

Muchas distribuciones utilizan valores predeterminados conservadores, en torno a 65.536, lo cual es suficiente para servicios sencillos, pero resulta insuficiente para cargas de búsqueda y análisis. En configuraciones típicas de alojamiento, utilizo 262 144 como un valor inicial sólido para pilas de mayor tamaño. Para instancias muy grandes de Elasticsearch/OpenSearch, preveo 1 048 576, siempre que los datos de medición apunten en esa dirección. Un valor más alto no aporta ninguna ventaja directa Aumento del rendimiento, evita errores cuando se requieren muchas asignaciones. La documentación del núcleo de Linux y los informes sobre prácticas habituales confirman esta clasificación.

Tipo de aplicación Perfil VMA (típico) Valor inicial de vm.max_map_count Límite máximo (si es necesario)
Pequeñas bases de datos / Herramientas bajo-medio 65.536 262.144
PostgreSQL/MySQL medio-alto 262.144 524.288
Elasticsearch/ OpenSearch alto-muy alto 262.144 1.048.576
Grandes pilas de Java medio-alto 262.144 524.288

Evaluar las necesidades actuales

Antes de cada modificación, compruebo la versión actual Configuración con sysctl vm.max_map_count o por cat /proc/sys/vm/max_map_count. A continuación, determino las necesidades reales de un proceso mediante wc -l /proc//maps, a ser posible bajo carga. Este valor varía en función de los módulos, las cachés y la carga de trabajo, por lo que lo observo a lo largo de varias ventanas de carga. En cuanto el pico alcanza entre 50 y 70 % del límite, establezco una reserva adecuada. De este modo, tomo una decisión fundamentada Decisión en lugar de adivinar.

¿Cómo puedo ajustar vm.max_map_count de forma segura?

Para las pruebas, establezco el valor temporalmente con sysctl -w vm.max_map_count=262144, lo cual surte efecto de inmediato y desaparece al reiniciar el sistema. Para un funcionamiento continuo, introduzco el valor en /etc/sysctl.conf y descárgalo con sysctl --system nuevo, para que la Configuración se mantiene. Los grandes clústeres de búsqueda o las pilas de bases de datos muy modulares se benefician, según la medición, de entre 524 288 y 1 048 576. Voy aumentando gradualmente, compruebo los registros y observo las métricas de uso del almacenamiento. Así es como mantengo el Riesgo Durante el funcionamiento, el consumo es reducido y se acumula un margen de seguridad previsible.

Buenas prácticas para entornos productivos

Realizo mediciones repetidas bajo cargas típicas y picos de carga, en lugar de basarme en valores puntuales. No establezco el límite máximo justo al límite, sino entre dos y cuatro veces por encima del pico observado. En los clústeres, elijo valores consistentes para que todos los nodos reaccionen de la misma manera y no haya Valores atípicos generar. El sistema de monitorización comprueba los errores relacionados con mmap/malloc, así como la evolución del número de VMA por proceso. Antes de la puesta en producción, pruebo las nuevas Valores en el entorno de prueba con una carga similar.

Interacción con otros parámetros del núcleo: swappiness, ratios de archivos sucios, límites de archivos

El parámetro «vm.max_map_count» nunca se considera de forma aislada, ya que hay otros factores que influyen en ello Conducta Lo mismo ocurre con el «swappiness», que determina la agresividad con la que el sistema traslada páginas al espacio de intercambio, lo que puede aumentar las latencias. Los «dirty ratios» controlan cuándo las páginas modificadas vuelven al disco, lo que puede suavizar o agravar los picos de E/S. Los límites para los archivos abiertos determinan cuántos archivos y sockets pueden mantener las bases de datos en paralelo. Compruebo estos Parámetros juntos, para que no se cree un nuevo cuello de botella.

Comprobar de forma selectiva las «Transparent Huge Pages»

THP influye en la gestión de la memoria al agrupar páginas grandes y, con ello, modificar los patrones de acceso. Las bases de datos reaccionan de forma sensible a THP en función de la carga de trabajo, por lo que compruebo el estado y el modo, y los configuro en „madvise“ o „never“ cuando aumentan las latencias. En mi nota sobre Páginas enormes transparentes En resumen. Lo importante es respaldar el cambio con métricas y no realizar la transición a ciegas. De este modo, el Comportamiento de almacenamiento comprensible y reproducible.

Entender el almacenamiento en caché de impresión de VFS

La caché VFS almacena metadatos y contenidos de archivos en la memoria principal, por lo que compite con las páginas de la base de datos. Con el parámetro para el Impresión de la caché VFS Influyo en la rapidez con la que el sistema libera esta caché. Una presión demasiado alta puede aumentar la carga de E/S, mientras que una presión demasiado baja desplaza las cachés de la base de datos y perjudica las latencias. Realizo ajustes poco a poco y mido los efectos en la tasa de aciertos de la caché de páginas, el tiempo de espera de E/S y el rendimiento. Esto Ajuste fino A menudo tiene un efecto mayor de lo esperado cuando las bases de datos y los sistemas de archivos funcionan en estrecha colaboración.

Directrices y bases de datos de NUMA

Las arquitecturas NUMA distribuyen la memoria entre los nodos, lo que influye en los tiempos de acceso. Sin las políticas adecuadas, las páginas terminan en nodos „incorrectos“, lo que aumenta las latencias y las faltas de caché. Ofrezco información sobre modos y políticas en Directrices NUMA, incluyendo parámetros de inicio orientados a la práctica. Para procesos de base de datos de gran envergadura, establezco nodos preferentes y compruebo el intercalado, para que los accesos a la memoria local permanecer. La interacción con vm.max_map_count tiene un efecto positivo cuando los procesos obtienen muchas asignaciones mediante estrategias NUMA consistentes.

Cómo se producen los VMA y por qué pueden dispararse

Distingo tres fuentes principales de VMA: (1) asignaciones vinculadas a archivos (por ejemplo, segmentos de datos e índices de Elasticsearch/OpenSearch), (2) mapeos anónimos a través de asignadores (glibc, jemalloc, tcmalloc) y (3) pilas de subprocesos. Muchos objetos compartidos pequeños, código JIT (por ejemplo, en las JVM) y patrones de asignación fragmentados generan áreas adicionales. Cada hilo lleva consigo al menos una VMA de pila; a medida que aumenta el número de hilos de trabajo, también crece el número de VMA. Esto explica por qué los sistemas, con la misma cantidad de datos pero con más hilos o complementos, alcanzan antes sus límites.

Importante: Distingo entre „mucha memoria“ y „muchas asignaciones“. Las áreas grandes y contiguas rara vez suponen un problema. La situación se vuelve crítica cuando el software tiene que gestionar con frecuencia muchos objetos pequeños mmap utiliza (estrategias de asignación), carga bibliotecas de forma dinámica o asigna un gran número de archivos en paralelo.

La sobrecarga por cada VMA es moderada (unos cientos de bytes de datos de gestión). Un límite más alto amplía las estructuras teóricamente posibles sin ocupar memoria RAM, siempre y cuando los procesos no las utilicen. Solo cuando se crean realmente entre cientos de miles y millones de VMA, la carga de trabajo de gestión del núcleo se nota de forma apreciable.

Profundizar en los métodos de medición: registrar los picos de forma fiable

  • Realizo mediciones a diferentes horas del día y en momentos de máxima carga de trabajo (ejecuciones por lotes, reindexación, ventanas de mantenimiento).
  • No solo superviso un proceso, sino todo el conjunto de servicios críticos (base de datos, sidecars, agentes de copia de seguridad y supervisión).
  • Para obtener resultados repetibles, distingo entre „en frío“ (caché de página vacía) y „en caliente“ (caché llena) y documento las diferencias.

Herramientas prácticas para localizar puntos de acceso VMA:

# Los 10 procesos principales por número de VMA
for p in /proc/[0-9]*; do
 pid=${p##*/}; test -r "$p/maps" || continue
 c=$(wc -l /dev/null || echo 0)
 cmd=$(tr -d '\0' /dev/null)]}"
done | sort -k2,2nr | head -n 10

En el caso de los clústeres, analizo los resultados de varios nodos y busco valores atípicos sistemáticos (por ejemplo, determinados shards, extensiones específicas o versiones). Configuro alertas cuando un proceso supera el 70 % del límite de % o cuando la carga máxima muestra una tendencia al alza.

Resolución de problemas: mensajes típicos de registro y comprobaciones

Cuando se alcanza el límite, suelo ver mensajes como „Cannot allocate memory“, „mmap failed“, „failed to map segment from shared object“ o interrupciones del inicio sin que haya una clara escasez de RAM. En ese caso, compruebo lo siguiente:

  • grep -i mmap /var/log/* y registros específicos del servicio sobre avisos de ENOMEM
  • Número actual de asignaciones: wc -l /proc//maps
  • Límites de ulimit/nofile, ya que muchos archivos segmentados no se asignan correctamente si no hay suficientes archivos abiertos
  • Número de hilos (ps -eLo pid,comm,nlwp | sort -k3 -nr | head), ya que muchos subprocesos aumentan el valor de la VMA

Correlaciono estos resultados con los perfiles de carga (creación de índices, Vacuum/Analyze, importaciones a gran escala). Si la cifra de VMA muestra picos claros correspondientes a tareas concretas, dimensiono la reserva en consecuencia.

Contenedores, nube y orquestación: particularidades

En los contenedores hay vm.max_map_count en la práctica, suele ser una Configuración del host. Establezco el valor en el nodo (servidor físico o máquina virtual) mediante sysctl y descárgalo de forma permanente desde /etc/sysctl.conf o archivos en /etc/sysctl.d/. En entornos Docker, aunque puedo --sysctl Aunque se especifique, en la práctica vm.max_map_count se aplica a todo el host, por lo que tengo previsto aplicar el cambio a nivel de nodo. En los orquestadores (por ejemplo, Kubernetes), prefiero establecer el valor mediante Node-Init/Cloud-Init o la imagen de máquina, para que los pods se inicien correctamente sin privilegios. Importante: documento la opción elegida Línea de cumplimiento normativo (qué tipo de nodo contiene qué valor), para que la programación y el autoescalado se mantengan coherentes.

Automatización y cumplimiento normativo

Guardo la configuración „en forma de código“, por ejemplo, en la gestión de la configuración. A modo de ejemplo, utilizo un archivo «drop-in» de sysctl:

# /etc/sysctl.d/90-db-mappings.conf
vm.max_map_count = 524288

El despliegue se lleva a cabo de forma controlada (Staging → Canary → despliegue general). Inmediatamente después de las implementaciones, realizo comprobaciones de estado y verifico que los nuevos pods/servicios vean el mismo límite. Para las auditorías, incluyo datos de medición (VMA máximas, factor de reserva, fecha del último ajuste) en la documentación operativa.

Ajuste con overcommit y OOM-Killer

Un límite de VMA más alto no reduce el consumo de RAM, pero permite más asignaciones. En momentos de máxima carga, la interacción con las estrategias de overcommit y el OOM-Killer puede resultar relevante: si permito más asignaciones, los procesos pueden reservar memoria de forma más agresiva. Por lo tanto, considero que vm.overcommit_memory y vm.overcommit_ratio Lo tengo en cuenta y me aseguro de que haya reservas claras (swap/margen) o políticas de sobreasignación más restrictivas cuando las cargas de trabajo tienden a la sobreasignación. El objetivo es disponer de un margen de preaviso: en lugar de un error OOM repentino, recibo con antelación señales de aumento de las tasas de error o de latencia en el sistema de monitorización, que indican la necesidad de tomar medidas correctivas.

Casos extremos: 32 bits, muchos subprocesos, elección del asignador

  • Procesos de 32 bits: El espacio de direcciones virtual es más reducido, por lo que la fragmentación se nota antes. Aumentar el valor de vm.max_map_count no soluciona la falta de espacio de direcciones; en este caso, lo que ayuda son las compilaciones de 64 bits o un cambio de arquitectura.
  • Servicios con gran número de hilos: Cada hilo cuenta con al menos una VMA de pila propia. Si el número de trabajadores aumenta considerablemente, el número de VMA crece de forma lineal. Me aseguro de que los grupos de hilos estén limitados y se escalen de forma adecuada.
  • Asignador: Algunos asignadores utilizan mmap Excesivo para bloques grandes o muchos bloques pequeños. Cuando se observan picos llamativos de VMA, pruebo asignadores alternativos o sus opciones de ajuste para reducir el número de asignaciones.
  • Bibliotecas compartidas: La gran cantidad de módulos pequeños que se cargan dinámicamente hace que aumente el número de asignaciones. Voy a comprobar si es posible consolidar módulos o eliminar complementos innecesarios.

Lista de comprobación previa al cambio

  • Determinar y documentar los límites actuales
  • Medir picos de VMA específicos del proceso en varias ventanas de carga
  • Calcular la reserva (factor de 2 a 4 por encima del pico) y planificar las pruebas de staging
  • Comprobar los límites asociados (nofile), el número de subprocesos, el THP, el swappiness y los ratios de datos sucios
  • Activar la supervisión y las alertas sobre la proximidad a VMA, los errores de mmap y los eventos OOM
  • Definir la ruta de implementación y de reversión (Canary, ventana de mantenimiento, archivos sysctl.d)
  • Garantizar y documentar la consistencia del clúster y de los nodos

Planificación para la creación de clústeres y el crecimiento

No solo tengo en cuenta la situación actual, sino también el crecimiento previsto de los datos y los índices. Las nuevas funcionalidades, el aumento del número de clientes o las ampliaciones adicionales suelen incrementar el número de Asignaciones. Por eso, preveo un margen por encima del pico observado y documento la decisión de forma clara. En los clústeres, mantengo los valores sincronizados para que los nodos reaccionen de forma idéntica y la conmutación por error no falle al alcanzar los límites. Las comprobaciones periódicas durante las ventanas de mantenimiento garantizan la Continuidad de la configuración.

En resumen: configuración segura para servidores de bases de datos

Compruebo el límite actual, mido el número de VMA bajo carga y configuro vm.max_map_count dejando un margen de reserva. Para muchas cargas de trabajo de bases de datos y búsquedas, 262 144 funciona como valor inicial y 1.048.576 como nivel superior, en caso de que los valores de medición y el crecimiento lo requieran. El cambio no supone un aumento inmediato del rendimiento, pero evita errores cuando se necesitan muchas asignaciones. La estabilidad se consigue al analizar conjuntamente los registros, las métricas y los parámetros del núcleo relacionados. De este modo, el Gestión de bases de datos Resistente, fácil de planificar y preparado para cargas cada vez mayores.

Artículos de actualidad