# Dec 21st, 2021: \[es\] Tres recomendaciones para tener un clúster Elasticsearch saludable

**URL:** <https://discuss.elastic.co/t/dec-21st-2021-es-tres-recomendaciones-para-tener-un-cluster-elasticsearch-saludable/289328>\
**Category:** Advent Calendar\
**Created:** [December 21, 2021, 8:00am UTC](https://discuss.elastic.co/t/dec-21st-2021-es-tres-recomendaciones-para-tener-un-cluster-elasticsearch-saludable/289328 "2021-12-21T08:00:53Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Imma](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/imma/32/32013_2.png) [@Imma](https://discuss.elastic.co/u/Imma)\
**Post date:** [December 21, 2021, 8:00am UTC](https://discuss.elastic.co/t/dec-21st-2021-es-tres-recomendaciones-para-tener-un-cluster-elasticsearch-saludable/289328/1 "2021-12-21T08:00:53Z")

</div>

This article is also available in English:

> [@Dec 21st, 2021: \[en\] Top 3 recommendations to keep your Elasticsearch cluster healthy](https://discuss.elastic.co/t/289326):
>
> This article is also available in Spanish. [https://discuss.elastic.co/t/289328](https://discuss.elastic.co/t/289328) Working as an Elastic support engineer, we see a few tools that are very useful to have already in place when we need to help our customers troubleshoot their Elasticsearch clusters, or monitor to keep them healthy. Let’s review the top 3 with a few examples. 1. Know your REST APIs Knowing Elasticsearch [REST APIs](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/rest-apis.html) is very useful to keep your cluster healthy. Not only can they help you troubleshoot, but prevent issue…

En nuestro día a día de soporte en Elastic vemos algunas herramientas que son muy útiles cuando necesitamos ayudar a nuestros clientes a solucionar problemas en sus clústeres de Elasticsearch o monitorizar para mantenerlos saludables. Repasemos las 3 principales con algunos ejemplos.

#### 1. Conoce tus APIs REST

Conocer las [APIs REST](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/rest-apis.html) de Elasticsearch es muy útil para manter el clúster en buen estado. No solo ayudan a solucionar problemas, sino también a prevenirlos. Si se desea algo más legible para personas, empezaremos echando un vistazo a las [CAT APIs](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cat.html).

El primer paso para mantener el clúster en buen estado es mantenerlo en verde. Con una simple llamada a la [API de cluster health](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cluster-health.html):

```auto
GET /_cluster/health

```

Obtendremos una descripción general del estado de nuestro clúster.

```json
{
  "cluster_name": "eyeveebee-prod-cluster",
  "status": "red",
  "timed_out": false,
  "number_of_nodes": 30,
  "number_of_data_nodes": 27,
  "active_primary_shards": 15537,
  "active_shards": 26087,
  "relocating_shards": 0,
  "initializing_shards": 0,
  "unassigned_shards": 1,
  "delayed_unassigned_shards": 0,
  "number_of_pending_tasks": 209,
  "number_of_in_flight_fetch": 0,
  "task_max_waiting_in_queue_millis": 235940,
  "active_shards_percent_as_number": 99.99616762873977
}

```

En el ejemplo, tenemos un clúster en rojo. Podemos ver que tenemos un shard sin asignar, lo que hace que el estado del clúster sea rojo. El estado de un clúster es el del peor shard del peor índice. Por lo tanto, al menos algun índice o shard estarán en rojo.

Es importante mantener el clúster en verde. Las [alertas de Kibana](https://www.elastic.co/guide/en/kibana/7.16/kibana-alerts.html#kibana-alerts-cluster-alerts) pueden ayudarnos notificándonos cuando el clúster se vuelve amarillo (falta al menos una replica de un shard) o rojo (falta al menos un shard primario).

Para investigar cual es el índice que está en rojo, podemos usar el [CAT indices API](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cat-indices.html):

```auto
GET _cat/indices?v&s=health:desc,index&h=health,status,index,docs.count,pri,rep

```

Así localizaremos el índice rojo.

```auto
health status index docs.count pri rep
red open eventlogs-000007 1 1
green open .apm-agent-configuration 0 1 1
...

```

Con [CAT](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/cat-shards.html) [shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cat-shards.html) [API](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/cat-shards.html) podemos bajar a nivel de shard en el índice ‘eventlogs-000007’:

```auto
GET /_cat/shards?v&s=state:asc,node,index&h=index,shard,prirep,state,docs,node

```

Para ver que efectivamente tiene su shard primario en estado ‘UNASSIGNED’, no asignado.

```auto
index shard prirep state docs node
eventlogs-000007 0 p UNASSIGNED         
.apm-agent-configuration 0 p STARTED 0 instance-0000000012
...

```

Finalmente podemos usar [Cluster Allocation explain API](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cluster-allocation-explain.html) para llegar al motivo:

```json
GET _cluster/allocation/explain
{
  "index": "eventlogs-000007",
  "shard": 0,
  "primary": true
}

```

Obtendríamos una explicación similar a la siguiente, que debería permitirnos llegar a la causa raíz.

```json
{
  "index" : "eventlogs-000007",
  "shard" : 0,
  "primary" : false,
  "current_state" : "unassigned",
  "unassigned_info" : {
    "reason" : "NODE_LEFT",
    "at" : "2021-12-08T17:00:53.596Z",
    "details" : "node_left [gyv9cseHQyWD-FjLTfSnvA]",
    "last_allocation_status" : "no_attempt"
  },
  "can_allocate" : "no",
  "allocate_explanation" : "cannot allocate because allocation is not permitted to any of the nodes",
  "node_allocation_decisions" : [
    {
      "node_id" : "-PYVqLCLTSKjriA6UZthuw",
      "node_name" : "instance-0000000012",
      "transport_address" : "10.43.1.6:19294",
      "node_attributes" : {
        "xpack.installed" : "true",
        "data" : "hot",
        "transform.node" : "true"
      },
      "node_decision" : "no",
      "deciders" : [
        {
          "decider" : "same_shard",
          "decision" : "NO",
          "explanation" : "the node is above the high watermark cluster setting [cluster.routing.allocation.disk.watermark.high=90.0%], having less than the minimum required [90.0%] free space, actual free: [9.13%]"
        }
      ]
    },
    ...

```

En este caso, nos hemos quedado sin almacenamiento en nuestros nodos y no se pueden asignar shards. Algo que podríamos acabar de confirmar si quisiéramos utilizando [CAT allocation API](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cat-allocation.html).

Podemos prevenir llegar al [watermark de disco](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/modules-cluster.html#disk-based-shard-allocation) con [Kibana alerts for disk usage threshold](https://www.elastic.co/guide/en/kibana/7.16/kibana-alerts.html#kibana-alerts-disk-usage-threshold). Si mantenemos nuestros nodos alrededor del 75% de almacenamiento, tendremos colchón para crecer y mantener el clúster estable. A partir del 85% de almacenamiento utilizado (valor por defecto), tendremos limitaciones de asignación de shards.

No podemos enfatizar lo suficiente la importancia de planificar la retención de datos. [Index Lifecycle Management](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/index-lifecycle-management.html) y el uso de [Data Tiers](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/data-tiers.html) nos serán de gran ayuda para mantener el almacenamiento controlado. Muy recomendable leer la documentacion sobre [el tamaño de los shards](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/size-your-shards.html#size-your-shards), punto que es clave para mantener el clúster en estado óptimo.

No olvidemos tampoco los [snapshots](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/snapshot-restore-apis.html) de Elasticsearch, con su [snapshot lifecycle-management](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/snapshot-lifecycle-management.html), que nos permite estar preparados para escenarios de pérdida de datos. Asimismo configurar para [configurar para alta disponibilidad](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/high-availability.html).

También observamos, en el estado del clúster del ejemplo, que la cantidad de tareas pendientes es algo elevada. De nuevo el uso de CAT APIs, en este caso [CAT pending tasks API](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cat-pending-tasks.html), para revisar que tareas tenemos pendientes:

```auto
GET /_cat/pending_tasks?v

```

```auto
insertOrder timeInQueue priority source 
412717 5.2s NORMAL restore_snapshot[2021.12.17-.ds-logs-2021.12.09-000030-trdkfuewwkjaca] 
412718 2s NORMAL ilm-execute-cluster-state-steps [{"phase":"cold","action":"searchable_snapshot","name":"wait-for-index-color"} => {"phase":"cold","action":"searchable_snapshot","name":"copy-execution-state"}]
...
...

```

O podríamos usar [jq](https://stedolan.github.io/jq/) para agregar los resultados de [pending cluster tasks API](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/cluster-pending.html) de forma que podamos investigar más facilmente qué tipo de tareas tenemos pendientes.

```auto
curl --silent --compressed 'https://localhost:9200/_cluster/pending_tasks' | jq '.tasks[].source' -cMr | sed -e 's/[.*//' | sort | uniq -c

```

Esto nos daría una idea más clara de estas tareas agrupadas:

```auto
  1 restore_snapshot
 17 delete-index
183 ilm-execute-cluster-state-steps
  2 node-join
  4 update task state
  2 update-settings

```

Esto es solo para mostrar que, conociendo las API REST disponibles, podemos obtener información muy útil para evaluar el estado de nuestro clúster y ajustar nuestra arquitectura en consecuencia.

Para terminar esta sección, recomiendo echar un vistazo a [Elastic’s support diagnostics](https://github.com/elastic/support-diagnostics). Esas son las llamadas a las API REST que utilizamos en Elastic Support para ayudar a nuestros clientes a mantener sus clústeres en buen estado. O al blog “[Why does Elastic support keep asking for diagnostic files](https://www.elastic.co/blog/why-does-elastic-support-keep-asking-for-diagnostic-files)” que explica porque pedimos este diagnóstico.

#### 2. Sacarle partido al Monitoring y Alertas del Stack Elastic

La segunda recomendación es disponer de un [clúster de monitorización dedicado](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/monitoring-production.html) para entornos productivos. Las API REST nos brindan información en el moento, pero nos faltan los datos históricos. Si lo enviamos a un clúster de monitorización dedicado, nos ayudará a investigar incidentes, capacity planning, etc.

[Kibana alerts for the Elatic Stack monitoring](https://www.elastic.co/guide/en/kibana/7.16/kibana-alerts.html) nos notificará de potenciales problemas.

Un caso que vemos a menudos en soporte de Elastic, donde los datos de monitorización son útiles, es el hotspotting de nodos.

Si tenemos un clúster que presenta una CPU elevada, por ejemplo, durante la ingesta, en uno o solo algunos de los nodos de datos, mientras que los otros están inactivos; y esos nodos siguen cambiando. Podemos usar el monitoreo para confirmar nuestras sospechas.

Echemos un vistazo al UI de [Kibana Stack Monitoring](https://www.elastic.co/guide/en/kibana/7.16/xpack-monitoring.html) para nuestro clúster. De los 3 nodos que tenemos, sólo uno muestra un uso alto de CPU.

 ![](https://us1.discourse-cdn.com/elastic/original/3X/5/f/5fac5df5de207740be2d47b1358ab146ae012b6c.png)

Podríamos investigar más yendo a la pestaña de índices. En este caso, encontramos que durante la ventana en la que vemos un alto uso de CPU en un nodo, tenemos un índice, ‘log-201998’, que tiene una tasa de ingesta muy alta en comparación con el resto.

 ![](https://us1.discourse-cdn.com/elastic/original/3X/f/7/f772f426d8f283ec4f8d81d63a398301a9fcb9fc.png)

Si este índice tiene un shard primario y es el único con una tasa de ingesta alta, podríamos asignar 3 shards primarios en vez de 1, por lo que la carga se equilibraría entre las 3 instancias de datos que tenemos en este ejemplo.

Para clústeres más grandes y con más de un índice “hot”, la situación podría no ser tan sencilla. Es posible que se requiera limitar la cantidad de fragmentos para esos índices que terminan en cada nodo del clúster. Consulte nuestra documentación [evitar hotspots en nodos](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/size-your-shards.html#avoid-node-hotspots).

Tener un clúster de monitoring será de gran ayuda.

#### 3. Revisar logs proactivamente

Una última recomendación es revisar los logs de forma proactiva.

Podemos usar [el módulo de Filebeat para Elasticsearch](https://www.elastic.co/guide/en/beats/filebeat/7.16/filebeat-module-elasticsearch.html) para ingestar nuestros logs en el clúster de monitoring que acabamos de comentar. O incluso usar las capacidades del stack de [categorización de logs](https://www.elastic.co/guide/en/observability/7.16/categorize-logs.html) para descubrir comportamientos anómalos y generar alertas asociadas.

Un ejemplo que vemos a menudo con nuestros clientes es el mapeo [de tipo de datos](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/mapping-types.html) incorrecto en algunos índices.

Dependiendo de cómo configuremos los mappings en nuestros índices, es posible que estemos perdiendo documentos que provocan un conflicto de tipos. Si revisamos los registros de nuestro clúster, veríamos esos errores y podríamos actuar.

Tomemos el ejemplo de un documento que a veces tiene un valor numérico en la fuente que lo envía y, a veces, es alfanumérico. Si usamos los [mapeos dinámicos](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/mapping.html#mapping-dynamic) predeterminadas en vez de explícitos, y primero ingerimos este documento con un valor numérico de un campo, lo llamaremos “key”:

```auto
POST my-test-index/_doc
{
  "key": 0
}

```

Elasticsearch interpretará este campo como un [número](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/number.html), de tipo long.

```auto
GET my-test-index/_mapping/field/key

```

```json
{
  "my-test-index" : {
    "mappings" : {
      "key" : {
        "full_name" : "key",
        "mapping" : {
          "key" : {
            "type" : "long"
          }
        }
      }
    }
  }
}

```

I si el siguiente documento lleva en este campo, por poner un ejemplo, un UUID:

```auto
POST my-test-index/_doc
{
  "key": "123e4567-e89b-12d3-a456-426614174000"
}

```

En Kibana Dev Tools veríamos el error.

```json
{
  "error" : {
    "root_cause" : [
      {
        "type" : "mapper_parsing_exception",
        "reason" : "failed to parse field [key] of type [long] in document with id '4Wtyz30BtaU7QP7QuSQY'. Preview of field's value: '123e4567-e89b-12d3-a456-426614174000'"
      }
    ],
    "type" : "mapper_parsing_exception",
    "reason" : "failed to parse field [key] of type [long] in document with id '4Wtyz30BtaU7QP7QuSQY'. Preview of field's value: '123e4567-e89b-12d3-a456-426614174000'",
    "caused_by" : {
      "type" : "illegal_argument_exception",
      "reason" : "For input string: "123e4567-e89b-12d3-a456-426614174000""
    }
  },
  "status" : 400
}

```

Este código 400 es un error no recuperable y significa que Elasticsearch no indexará el documento y los clientes como Logstash o Agent no volverán a intentarlo.

Si buscamos nuestros documentos en el índice, solo tenemos el primero.

```auto
GET my-test-index/_search?filter_path=hits.total,hits.hits._source

```

```json
{
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "hits" : [
      {
        "_source" : {
          "key" : 0
        }
      }
    ]
  }
}

```

Esto que vemos en Kibana, también aparecería en nuestros logs. Es muy habitual que encontremos esto en Logstash (registros que también podemos ingerir usando el [módulo Logstash de Filebeat](https://www.elastic.co/guide/en/beats/filebeat/7.16/filebeat-module-logstash.html)). Podría pasar desapercibido a menos que revisemos nuestros registros.

```auto
Could not index event to Elasticsearch. {:status=>400, :action=>["index", {:_id=>nil, :_index=>"my-test-index-0000001", :routing=>nil, :_type=>"_doc"}, #<LogStash::Event:0x5662a9f3>], :response=>{"index"=>{"_index"=>"my-test-index-0000001", "_type"=>"_doc", "_id"=>"Qmt6z30BtaU7QP7Q4SXE", "status"=>400, "error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse field [key] of type [long] in document with id 'Qmt6z30BtaU7QP7Q4SXE'

```

Adicionalmente, si ingestamos logs, estaremos preparados para revisar los [slow logs](https://www.elastic.co/guide/en/elasticsearch/reference/7.16/index-modules-slowlog.html) en el caso que necesitemos resolver algun problema relacionado con lentitud de búsquedas o de ingesta.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 18, 2022, 8:01am UTC](https://discuss.elastic.co/t/dec-21st-2021-es-tres-recomendaciones-para-tener-un-cluster-elasticsearch-saludable/289328/2 "2022-01-18T08:01:42Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
