Cómo lidiar con unassigned shards en Elasticsearch


Lo primero es lo primero, saber qué significa el estado del cluster de elasticsearch:

  • Green: Cluster 100% operacional con todos los shards, tanto primarios como réplicas asignados.
  • Yellow: Todos los shards primarios asignados, pero al menos hay problemas con una réplica. El funcionamiento de las búsquedas no se ve afectado, pero la alta disponibilidad del cluster podría estar comprometida.
  • Red: Al menos un shard primario tiene problemas. Tus búsquedas devolverán resultados incompletos y el indexado podría devolver alguna excepción.

Fuentes: [elastic.co] [chrissimpson.co.uk]

Red cluster. ¿Y ahora qué?

En el siguiente ejemplo, vemos un cluster en estado RED, con 2 shards no asignados.

[ec2-user@myfakeserver ~]$ curl http://elasticsearch.myfakecluster.com:9200/_cluster/health?pretty
{
  "cluster_name" : "myfakecluster",
  "status" : "red",
  "timed_out" : false,
  "number_of_nodes" : 6,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 44,
  "active_shards" : 88,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 2,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 97.77777777777777
}

Muchas de las ocasiones en los que me he encontrado con un cluster con unassigned shards ha sido por falta de espacio en disco, ya sea porque el cluster en sí se estaba quedando sin espacio, o porque había caído alguno de los data nodes. Así pues, tras verificar que no haya problemas de espacio, seguramente deberíamos revisar que el cluster tenga el número y tipo de nodos esperados.

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cat/nodes?v
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
10.10.13.74            62          69   1    0.01    0.01     0.00 m         *      i-00e943d383ac0e36a
10.10.12.224           10          74   0    0.00    0.00     0.00 di        -      i-0fb30da02fa44654f
10.10.14.191           17          68   1    0.30    0.16     0.05 m         -      i-0c3f5e9ffe51580de
10.10.13.26            10          75   0    0.00    0.00     0.00 di        -      i-088d4398987bbcbe4
10.10.14.79            21          71   0    0.00    0.00     0.00 di        -      i-0d02b207abeb67c6b
10.10.12.4             34          68   1    0.04    0.03     0.00 m         -      i-087e0c009c10493d6

Asignación automática de shards fallidos

El comando mágico para decirle al cluster que vuelva a intentar asignar los unassigned shards, sin más, es símplemente lanzar un POST con un body vacío («{}») contra la siguiente url:

/_cluster/reroute?retry_failed=true

Por cierto, si tienes problemas de espacio, verás que tras eliminar índices no se libera espacio. Esto es debido a cómo Lucene trabaja, que marca los documentos para ser eliminados pero no los elimina hasta que las operaciones de merge internas se ejecutan. Y ésto pasa cuando Lucene decide que pase. Una forma de forzar el merge de los segmentos, únicamente para los índices eliminados es mediante /_forcemerge?only_expunge_deletes=true

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_forcemerge?only_expunge_deletes=true

Otra llamada que es oro es /_cluster/allocation/explain la cual nos dará la razón del porqué no se han podido asignar los shards. Merece la pena pararse a leer el output.

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cluster/allocation/explain?pretty/pre>

Asignación manual de shards

Si hemos confirmado que no ha caído ningún nodo y que no tenemos problemas de espacio, pasaremos a revisar los shards.

Algo a remarcar es que Elasticsearch siempre intentará re-assignar los shards «unassigned», así pues siempre es una buena idea darle un tiempo prudencial al cluster para que trate de solucionar por él mismo los unassigned shards mientras revisamos los logs.

Si queremos forzar a assignar los shards, lo primero que tendremos que hacer es tener claros qué shards estan unassigned, y entender dónde deberían haberse asignado. Podemos usar _cat/shards para listar todos los shards, obteniendo detalles sobre su estado y su tipo (primario o réplica), y mediante grep ver directamente los shards que no están asignados. Recordemos que si al menos uno de los shards es de tipo primary (prirep = p) el cluster estará en status RED.

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cat/shards?v | egrep -i "index|unassigned"
index                      shard prirep state         docs   store ip            node                              
fakeindx-20181120            0     r      UNASSIGNED
anotherindx-20180103         1     p      UNASSIGNED
anotherindx-20180103         1     r      UNASSIGNED
anotherindx-20180103         3     r      UNASSIGNED

Del output anterior, nos interesará identificar:

  • El índice (o índices) al que pertenecen los unassigned shards
  • El número de shard

En el ejemplo anterior, tenemos dos índices con unassigned shards.

Empezaremos listando todos los shards del primer índice (fakeindx-20181120 en el ejemplo)

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cat/shards | grep -i fakeindx-20181120
fakeindx-20181120         0 p STARTED 27298169  21.7gb 10.10.53.120 instance-0000000020
fakeindx-20181120         0 r UNASSIGNED
fakeindx-20181120         1 p STARTED 27298169  21.7gb 10.10.53.120 instance-0000000020
fakeindx-20181120         1 r STARTED 27298169  21.7gb 10.10.53.121 instance-0000000021

En la salida anterior vemos como fakeindx-20181120 tiene únicamente dos shards (números 0 y 1) con una réplica cada uno. Además, vemos como el shard 1 tiene asignado el shard primario en el nodo instance-0000000020 y su réplica en el nodo instance-0000000021. Así pues, podríamos pensar en asignar la réplica del shard 0 que actualmente está unassigned, también al nodo instance-0000000021. Para ello primero, querríamos confirmar cómo tiene asignados los shards un índice «healthy» del mismo tipo.

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cat/shards | grep -i fakeindx-20181120
fakeindx-20181119         0 p STARTED 27298169  21.7gb 10.10.53.120 instance-0000000020
fakeindx-20181119         1 r STARTED 27298169  21.7gb 10.10.53.121 instance-0000000021
fakeindx-20181119         1 p STARTED 27298169  21.7gb 10.10.53.120 instance-0000000020
fakeindx-20181119         1 r STARTED 27298169  21.7gb 10.10.53.121 instance-0000000021

Tras confirmar que parece bastante evidente que el shard unassigned debería ir al nodo instance-0000000021, podemos forzar su asignación con _cluster/reroute. Ojo, antes de darle al intro, confirma tu versión de Elasticsearch. Los comandos de este artículo se han probado con la versión 5.6, así que aunque seguramente no varíen mucho entre versiones, vale la pena revisarlo.

curl -XPOST 'http://elasticsearch.myfakecluster.com:9200/_cluster/reroute' -d '{
{
    "commands" : [
        {
          "allocate_replica" : {
                "index" : "fakeindx-20181120",
                "shard" : 0,
                "node" : "instance-0000000020"
          }
        }
    ]
}

La operación anterior debería devolver un OK o en su defecto, el mensaje de error con la explicación de la razón por la que no se ha podido realizar la asignación.

Prueba usar /_cluster/reroute?retry_failed=true si la operación anterior lanza un error referente al máximo de retries.

Fuentes: https://www.elastic.co/blog/red-elasticsearch-cluster-panic-no-longer

2 respuestas a «Cómo lidiar con unassigned shards en Elasticsearch»

Deja una respuesta

Tu dirección de correo electrónico no será publicada.