Gestión y solución de problemas de la memoria de Elasticsearch
.jpg)
Con Elastic Cloud ofreciendo soluciones como Observability, Security y búsqueda, hemos ampliado el número de usuarios que usan Elastic Cloud más allá de los equipos completos de operaciones para incluir ingenieros de datos, equipos de seguridad y consultores. Como representante de soporte de Elastic, disfruté interactuar con una amplia gama de usuarios y casos de uso.
Dada la audiencia más amplia, veo más preguntas sobre la gestión de asignación de recursos, en particular sobre cómo solucionar problemas de salud de la asignación y evitar interruptores de circuito. Lo entiendo. Cuando empecé con Elasticsearch, tenía las mismas preguntas. Fue mi primera introducción a la gestión de heap de Java y shards de base de datos temporales, y al escalado de mi propia infraestructura.
Cuando me uní a Elastic, me gustó tener blogs y tutoriales (además de la documentación) para poder incorporarme rápido. Sin embargo, durante el primer mes tuve problemas para relacionar mi conocimiento teórico con los errores que enviaban los usuarios en la cola de tickets. Eventualmente descubrí, como otros representantes de soporte, que muchos de los errores reportados eran solo síntomas de problemas de asignación y que los mismos siete (aproximadamente) enlaces permitirían a los usuarios ponerse al día para gestionar con éxito su asignación de recursos.
Desde el punto de vista de un representante de soporte, haré un repaso de los enlaces principales de la teoría de gestión de asignación que enviamos a los usuarios, los principales síntomas que vemos y a dónde dirigimos a los usuarios para actualizar sus configuraciones y resolver los problemas de asignación de recursos.
Teoría
Como aplicación Java, Elasticsearch requiere cierta asignación de memoria lógica (heap) desde la memoria física del sistema. Esto debería ser hasta la mitad de la RAM física, con un límite de 32 GB. Establecer un mayor uso del heap suele ser en respuesta a consultas costosas y a un mayor almacenamiento de datos. Circuit breaker principal está por defecto al 95 %, pero recomendamos escalar recursos una vez que llegue consistentemente al 85 %.
Recomendamos enfáticamente estos artículos de visión general para obtener más información:
Configuración
De inmediato, la configuración predeterminada de Elasticsearch ajusta automáticamente el tamaño de tu heap de JVM según el rol del Node y la memoria total. Sin embargo, según sea necesario, puedes configurarlo directamente de las siguientes tres maneras:
1. Directamente en el archivoconfig > jvm.options local de Elasticsearch:
## JVM configuration
################################################################
## IMPORTANT: JVM heap size
################################################################
…
# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space
-Xms4g
-Xmx4g2. Como variable de entorno de Elasticsearch en tu docker-compose:
version: '2.2'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.12.0
environment:
- node.name=es01
- cluster.name=es
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
- discovery.type=single-node
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9200:92003. A través de nuestro Elastic Cloud Hosted > despliegue > Editar vista. Nota: El desplegable asigna memoria física y aproximadamente la mitad se asignará al heap.

Solución de problemas
Si actualmente tienes problemas de rendimiento con tu cluster, lo más probable es que los sospechosos habituales sean los culpables:
- Problemas de configuración: Nodos maestros de tamaño insuficiente, sin política ILM
- Inducidos por el volumen: alta velocidad/carga de solicitudes, solapamiento de consultas/escrituras costosas
Estado de la asignación
Los índices de datos se almacenan en subfragmentos, que emplean el heap para mantenimiento y durante las solicitudes de búsqueda/escritura. El tamaño del fragmento no debe ser mayor de 50 GB. Tomando el ejemplo anterior de Elastic Cloud Hosted con 8 GB de memoria física en dos zonas (que asignan dos nodos en total), vamos a unir esto a un ejemplo: _cat/allocation.
GET /_cat/allocation?v=true&h=shards,node
shards node
41 instance-0000000001
41 instance-0000000000Y para: _cluster/health.
GET /_cluster/health?filter_path=status,*_shards
{
"status": "green",
"unassigned_shards": 0,
"initializing_shards": 0,
"active_primary_shards": 41,
"relocating_shards": 0,
"active_shards": 82,
"delayed_unassigned_shards": 0
}Si algún shard reporta >0 fuera de active_shards o active_primary_shards, se ha identificado una causa de los problemas de rendimiento.
Lo más común es que si se informa de un problema, será unassigned_shards>0. Si estos shards son primarios, tu clúster informará como status:red, y si solo son réplicas, informará como status:yellow. (Por eso configurar réplicas en los índices: si el clúster encuentra un problema, puede recuperar en lugar de experimentar pérdida de datos). Imaginemos que tenemos un status:yellow con un único shard no asignado. Para investigar, echaríamos un vistazo a qué shard del índice está teniendo problemas a través de _cat/shards.
GET _cat/shards?v=true&s=state
index shard prirep state docs store ip node
logs 0 p STARTED 2 10.1kb 10.42.255.40 instance-0000000001
logs 0 r UNASSIGNED
kibana_sample_data_logs 0 p STARTED 14074 10.6mb 10.42.255.40 instance-0000000001
.kibana_1 0 p STARTED 2261 3.8mb 10.42.255.40 instance-0000000001Así que esto será para nuestros logs de índice que no son del sistema, que tienen una réplica no asignada de shard. Veamos qué le está causando problemas ejecutando _cluster/allocation/explain. (Consejo profesional: cuando escalas a soporte, esto es exactamente lo que hacemos).
GET _cluster/allocation/explain?pretty&filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*
{ "index": "logs",
"node_allocation_decisions": [{
"node_name": "instance-0000000005",
"deciders": [{
"decider": "data_tier",
"decision": "NO",
"explanation": "node does not match any index setting [index.routing.allocation.include._tier] tier filters [data_hot]"
}]}]}Este mensaje de error apunta a data_hot, que forma parte de una política de gestión del ciclo de vida de los índices (ILM), e indica que nuestra política ILM es incompatible con la configuración actual del índice. En este caso, la causa del error es configurar una política ILM caliente-tibia sin haber designado nodos caliente y tibio. (Necesitaba cerciorarme de que algo fallara, así que les presento ejemplos de errores. Para más información, consulten este video de ejemplo para la resolución de problemas).
Si ejecutas este comando cuando no tienes ningún shard sin asignar, recibirás un error 400 que indica que no se pueden encontrar shards sin asignar para explicar porque no hay nada malo que reportar.Si recibes una causa no lógica (por ejemplo, un error de red temporal como que el nodo abandona el clúster durante la asignación), puedes usar la práctica herramienta _cluster/reroute de Elastic.
POST /_cluster/rerouteEsta solicitud sin personalizaciones inicia un proceso en segundo plano asincrónico que intenta asignar todos los fragmentos con estado actual UNASSIGNED. (No seas como yo y no esperes a que termine antes de ponerte en contacto con el equipo de desarrollo, porque pensé que sería instantáneo y casualmente se intensificaría justo a tiempo para que ellos digan que no pasa nada porque ya no hay nada). Para obtener más información, consulta este video de solución de problemas para monitorear el estado de asignación.
Interruptores de circuito
Al alcanzar el máximo de la asignación de heap, las solicitudes a tu clúster pueden agotarse o generar errores y, con frecuencia, tu clúster experimentará excepciones de interruptor de circuito. Errores de interruptor de circuito causan eventos en elasticsearch.log como:
Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [num/numGB], which is larger than the limit of [num/numGB], usages [request=0/0b, fielddata=num/numKB, in_flight_requests=num/numGB, accounting=num/numGB]Para investigar, echa un vistazo a su heap.percent, ya sea mirando _cat/nodes:
GET /_cat/nodes?v=true&h=name,node*,heap*
# heap = JVM (logical memory reserved for heap)
# ram = physical memory
name node.role heap.current heap.percent heap.max
tiebreaker-0000000002 mv 119.8mb 23 508mb
instance-0000000001 himrst 1.8gb 48 3.9gb
instance-0000000000 himrst 2.8gb 73 3.9gbO si ya lo activaste antes, navega a Kibana > Stack Monitoring.

Si confirmaste que estás llegando a los interruptores de circuito de memoria, quizá te convenga aumentar temporalmente la memoria heap para tener un margen que te permita investigar. Al investigar la causa raíz, revisa tus logs de auditoría, registro lento, clusterlogs, o elasticsearch.log de los eventos consecutivos anteriores. Estarás buscando:
- Búsquedas costosas, específicamente:
- Muchas agregaciones de cubetas
- Me sentí muy avergonzado cuando descubrí que las búsquedas asignan temporalmente una parte determinada de tu heap antes de ejecutar la búsqueda según el tamaño de la búsqueda o las dimensiones de la cubeta, por lo que configurar 10 000 000 realmente le estaba dando acidez a mi equipo de operaciones.
- mapeos no optimizados
- El segundo motivo por el cual me sentí avergonzado fue por creer que hacer reportes jerárquicos permitiría mejores búsquedas que los datos aplanados (pero no es así).
- Muchas agregaciones de cubetas
- Volumen/ritmo de solicitudes: normalmente consultas por batch o asíncronas
Momento de escalar
Si esta no es la primera vez que activas los disyuntores o sospechas que será un problema continuo (por ejemplo, llegar constantemente al 85 %; entonces es hora de analizar los recursos de escalado), querrás echar un vistazo más de cerca a la presión de memoria JVM como tu indicador a largo plazo del montón. Puedes verificar esto en Elastic Cloud Hosted > Despliegue.

O puedes calcularlo a partir de _nodes/stats:
GET /_nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
{"nodes": { "node_id": { "jvm": { "mem": { "pools": { "old": {
"max_in_bytes": 532676608,
"peak_max_in_bytes": 532676608,
"peak_used_in_bytes": 104465408,
"used_in_bytes": 104465408
}}}}}}}Dónde:
JVM Memory Pressure = used_in_bytes / max_in_bytesUn síntoma potencial de esto es la alta frecuencia y la larga duración de eventos del recolector de basura (gc) en tu elasticsearch.log:
[timestamp_short_interval_from_last][INFO ][o.e.m.j.JvmGcMonitorService] [node_id] [gc][number] overhead, spent [21s] collecting in the last [40s]Si confirmas este escenario, deberás evaluar escalar tu cluster o reducir las demandas que le llegan. Te convendrá investigar/considerar:
- Aumentar los recursos de heap (heap/nodo; cantidad de nodos)
- Disminuir los fragmentos (eliminar datos innecesarios/antiguos; usar ILM para colocar los datos en almacenamiento en caliente/frío para poder reducirlos; desactivar las réplicas para los datos cuya pérdida no importe)
Estamos aquí para ayudarte
¡Guau! Por lo que veo en Soporte de Elastic, ese es el resumen de los tickets más comunes de los usuarios: shards sin asignar, shard-heap desequilibrado, interruptores de circuito, alta recolección de basura y errores de asignación. Todos son síntomas de la conversación sobre gestión de asignación de recursos principal. Afortunadamente, ahora conoces la teoría y los pasos de resolución, también.
Sin embargo, si en este punto estás atascado resolviendo un problema, siéntete libre de ponerte en contacto. Estamos aquí para ayudarte ¡y nos complace hacerlo! Contáctanos:
- Elastic Discuss
- Slack de la comunidad de Elastic
- Consultoría de Elastic
- Capacitación de Elastic
- Soporte de Elastic
¡Celebremos nuestra capacidad de autogestionar la asignación de recursos del Elastic Stack "sin Operaciones" (y también "con Operaciones")!
Recursos adicionales:
Publicado originalmente el 27 de abril de 2021; actualizado el 5 de noviembre de 2024.
El momento del lanzamiento de cualquiera de las características o funcionalidades descritas en esta publicación queda a exclusivo criterio de Elastic. Es posible que algunas características o funcionalidades que no estén disponibles en este momento no se lancen a tiempo o no se lancen en absoluto.