ElasticSearch: Shards não atribuídos, como consertar?


165

Eu tenho um cluster ES com 4 nós:

number_of_replicas: 1
search01 - master: false, data: false
search02 - master: true, data: true
search03 - master: false, data: true
search04 - master: false, data: true

Eu tive que reiniciar o search03 e, quando voltou, voltou ao cluster sem problemas, mas deixou 7 shards não atribuídos espalhados.

{
  "cluster_name" : "tweedle",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 4,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 15,
  "active_shards" : 23,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 7
}

Agora meu cluster está no estado amarelo. Qual é a melhor maneira de resolver esse problema?

  • Excluir (cancelar) os fragmentos?
  • Mover os shards para outro nó?
  • Alocar os shards para o nó?
  • Atualizar 'number_of_replicas' para 2?
  • Algo completamente diferente?

Curiosamente, quando um novo índice foi adicionado, esse nó começou a trabalhar nele e se saiu bem com o restante do cluster, deixando apenas os fragmentos não atribuídos espalhados.

Siga a pergunta: estou fazendo algo errado para que isso aconteça em primeiro lugar? Não tenho muita confiança em um cluster que se comporta dessa maneira quando um nó é reiniciado.

NOTA: Se você estiver executando um cluster de nó único por algum motivo, poderá simplesmente fazer o seguinte:

curl -XPUT 'localhost:9200/_settings' -d '
{
    "index" : {
        "number_of_replicas" : 0
    }
}'

Respostas:


117

Por padrão, o Elasticsearch irá atribuir shards aos nós dinamicamente. No entanto, se você desabilitou a alocação de shard (talvez tenha feito uma reinicialização contínua e esqueceu de reativá-la), poderá reativar a alocação de shard.

# v0.90.x and earlier
curl -XPUT 'localhost:9200/_settings' -d '{
    "index.routing.allocation.disable_allocation": false
}'

# v1.0+
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
    "transient" : {
        "cluster.routing.allocation.enable" : "all"
    }
}'

O Elasticsearch reatribuirá os shards normalmente. Isso pode ser lento, considere aumentar indices.recovery.max_bytes_per_sece cluster.routing.allocation.node_concurrent_recoveriesacelerar.

Se você ainda estiver com problemas, provavelmente algo está errado, procure erros nos logs do Elasticsearch. Se você virEsRejectedExecutionException seus pools de threads, talvez seja muito pequeno .

Por fim, você pode reatribuir explicitamente um shard a um nó com a API de redirecionamento .

# Suppose shard 4 of index "my-index" is unassigned, so you want to
# assign it to node search03:
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
    "commands": [{
        "allocate": {
            "index": "my-index",
            "shard": 4,
            "node": "search03",
            "allow_primary": 1
        }
    }]
}'

3
Quando eu fiz isso eu tenho: { "error" : "ElasticsearchIllegalArgumentException[[allocate] failed to find [logstash-2015.01.05][1] on the list of unassigned shards]", "status" : 400 } Mesmo que eu posso ver que caco é um dos mais não alocados em ES-Head
wjimenez5271

Aliás, outros shards funcionaram como alocados, e os demais se consertaram.
wjimenez5271 12/01

este é um ótimo conselho.
Yehosef

1
Desde o release 5.0, o comando "alocar" foi alterado para fornecer mais opções - o exemplo acima agora seria "alocate_empty_primary", omitindo o parâmetro "allow_primary".
jmb

4
você precisa adicionar -H 'Content-Type: application/json'se receber o erro #Content-Type header [application/x-www-form-urlencoded] is not supported
luckydonald 7/17/17

56

OK, resolvi isso com alguma ajuda do suporte do ES. Emita o seguinte comando para a API em todos os nós (ou nos nós que você acredita serem a causa do problema):

curl -XPUT 'localhost:9200/<index>/_settings' \
    -d '{"index.routing.allocation.disable_allocation": false}'

onde <index>está o índice que você acredita ser o culpado. Se você não tem ideia, basta executar isso em todos os nós:

curl -XPUT 'localhost:9200/_settings' \
    -d '{"index.routing.allocation.disable_allocation": false}'

Também adicionei esta linha à minha configuração do yaml e, desde então, qualquer reinicialização do servidor / serviço ficou livre de problemas. Os fragmentos foram realocados de volta imediatamente.

FWIW, para responder a uma pergunta muito procurada, defina MAX_HEAP_SIZE como 30G, a menos que sua máquina tenha menos de 60G de RAM; nesse caso, defina-a como metade da memória disponível.

Referências


2
Para resolver isso na versão 1.1.1, devo usar cluster.routing.allocation.enable = none?
User3175226

1
Alocação disable não está documentado lá, pelo menos não a partir de novembro 20.

3
Observe que a alocação de roteamento é uma configuração em todo o cluster; portanto, não importa para qual nó você envia o comando.
Wilfred Hughes

Eu adicionei ambos no meu arquivo es yml. index.routing.allocation.disable_allocation : false cluster.routing.allocation.enable: noneMas ainda estão aparecendo os fragmentos não atribuídos. Qual pode ser o motivo?
Bagui

1
Na versão 6.8, recebo um erro:{ "type": "illegal_argument_exception", "reason": "unknown setting [index.routing.allocation.disable_allocation] please check that any required plugins are installed, or check the breaking changes documentation for removed settings" } ],
Janac Meena 13/01

39

Este pequeno script do bash será forçado a reatribuir, você poderá perder dados.

NODE="YOUR NODE NAME"
IFS=$'\n'
for line in $(curl -s 'localhost:9200/_cat/shards' | fgrep UNASSIGNED); do
  INDEX=$(echo $line | (awk '{print $1}'))
  SHARD=$(echo $line | (awk '{print $2}'))

  curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
     "commands": [
        {
            "allocate": {
                "index": "'$INDEX'",
                "shard": '$SHARD',
                "node": "'$NODE'",
                "allow_primary": true
          }
        }
    ]
  }'
done

Funcionou como um encanto. Obrigado!
Paulo Pires

Eu recebi este erro: <br> {"error": "JsonParseException [Caractere inesperado (',' (código 44)): esperava um valor válido (número, String, matriz, objeto, 'true', 'false' ou 'null') \ n em [Fonte: [B @ 3b1fadfb; line: 6, coluna: 27]] "," status ": 500} <br> <br> o que devo fazer para corrigi-lo
biolinh 30/03/15

Muito obrigado! Economizou tempo precioso !!
Sathish

O script lança o erro:{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}
Janac Meena 13/01

17

A única coisa que funcionou para mim foi alterar o número_de_replicas (eu tinha duas réplicas, então mudei para 1 e depois mudei novamente para 2).

Primeiro:

PUT /myindex/_settings
{
    "index" : {
        "number_of_replicas" : 1
     }
}

Então:

PUT /myindex/_settings
{
    "index" : {
        "number_of_replicas" : 2
     }
}

(Eu já respondi nesta pergunta )


9

O Elasticsearch aloca automaticamente shards se a configuração abaixo estiver definida para todos. Essa configuração pode ser definida usando uma API de resto, bem como cluster.routing.allocation.enable: all

Se mesmo após a aplicação das configurações abaixo, es falhar ao atribuir os shards automaticamente, você precisará forçar a atribuição dos shards. ES link oficial para este

Eu escrevi um script para forçar a atribuição de todos os shards não atribuídos no cluster.

A matriz abaixo contém uma lista de nós entre os quais você deseja equilibrar os shards não atribuídos

#!/bin/bash
array=( node1 node2 node3 )
node_counter=0
length=${#array[@]}
IFS=$'\n'
for line in $(curl -s 'http://127.0.0.1:9200/_cat/shards'|  fgrep UNASSIGNED); do
    INDEX=$(echo $line | (awk '{print $1}'))
    SHARD=$(echo $line | (awk '{print $2}'))
    NODE=${array[$node_counter]}
    echo $NODE
    curl -XPOST 'http://127.0.0.1:9200/_cluster/reroute' -d '{
        "commands": [
        {
            "allocate": {
                "index": "'$INDEX'",
                "shard": '$SHARD',
                "node": "'$NODE'",
                "allow_primary": true
            }
        }
        ]
    }'
    node_counter=$(((node_counter)%length +1))
done

Esse script não funcionou, ou seja, depois que eu o executei, eu ainda tinha fragmentos NÃO-atribuídos.
21417 Chris F

@ChrisF Na linha1: você precisa substituir node1, node2, node3 pelos nomes reais do nó. Você pode obtê-los com um host local curl: 9200 / _cat / nós.
sidi

6

Hoje fiquei com o mesmo problema de alocação de shards. O script que W. Andrew Loe III propôs em sua resposta não funcionou para mim, então eu o modifiquei um pouco e finalmente funcionou:

#!/usr/bin/env bash

# The script performs force relocation of all unassigned shards, 
# of all indices to a specified node (NODE variable)

ES_HOST="<elasticsearch host>"
NODE="<node name>"

curl ${ES_HOST}:9200/_cat/shards > shards
grep "UNASSIGNED" shards > unassigned_shards

while read LINE; do
  IFS=" " read -r -a ARRAY <<< "$LINE"
  INDEX=${ARRAY[0]}
  SHARD=${ARRAY[1]}

  echo "Relocating:"
  echo "Index: ${INDEX}"
  echo "Shard: ${SHARD}"
  echo "To node: ${NODE}"

  curl -s -XPOST "${ES_HOST}:9200/_cluster/reroute" -d "{
    \"commands\": [
       {
         \"allocate\": {
           \"index\": \"${INDEX}\",
           \"shard\": ${SHARD},
           \"node\": \"${NODE}\",
           \"allow_primary\": true
         }
       }
     ]
  }"; echo
  echo "------------------------------"
done <unassigned_shards

rm shards
rm unassigned_shards

exit 0

Agora, eu não sou um tipo de guru do Bash, mas o script realmente funcionou para o meu caso. Observe que você precisará especificar valores apropriados para as variáveis ​​"ES_HOST" e "NODE".


infelizmente o ES5x quebrou a compatibilidade: elastic.co/guide/en/elasticsearch/reference/5.1/…
Fawix

2
Para que o script acima para trabalhar com ES5x substituir allocatecom allocate_empty_primarye substituir \"allow_primary\": truecom\"accept_data_loss\": true
Fawix

Ficar {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}quieto depois de aplicar a sugestão de
Fawix

6

No meu caso, o limite superior do espaço em disco foi atingido.

Veja este artigo: https://www.elastic.co/guide/en/elasticsearch/reference/current/disk-allocator.html

Basicamente, eu corri:

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "90%",
    "cluster.routing.allocation.disk.watermark.high": "95%",
    "cluster.info.update.interval": "1m"
  }
}

Para que aloque se <90% de espaço em disco usado e mova um fragmento para outra máquina no cluster se for usado> 95% de espaço em disco; e verifica a cada 1 minuto.


4

Talvez ajude alguém, mas tive o mesmo problema e foi devido à falta de espaço de armazenamento causado por um log muito grande.

Espero que ajude alguém! :)


4

No meu caso, quando eu crio um novo índice , o número_de_replicas padrão é definido como 1. E o número de nós no meu cluster era apenas um, portanto não havia nó extra para criar a réplica; portanto, a integridade estava ficando amarela. Então, quando eu criei o índice com a propriedade settings e defina o número_de_replicas como 0. Então funcionou bem. Espero que isto ajude.

PUT /customer
{
    "settings": {
        "number_of_replicas": 0
    }
}

3

Eu tive o mesmo problema, mas a causa raiz foi uma diferença nos números de versão (1.4.2 em dois nós (com problemas) e 1.4.4 em dois nós (ok)). As primeira e segunda respostas (definindo "index.routing.allocation.disable_allocation" como false e definindo "cluster.routing.allocation.enable" para "all") não funcionaram.

No entanto, a resposta de @Wilfred Hughes (definindo "cluster.routing.allocation.enable" para "all" usando transiente) me deu um erro com a seguinte declaração:

[NÃO (a versão do nó de destino [1.4.2] é mais antiga que a versão do nó de origem [1.4.4])]

Após atualizar os nós antigos para 1.4.4, esses nós começaram a ressnc com os outros bons nós.


3

Eu estava tendo esse problema também e achei uma maneira fácil de resolvê-lo.

  • Obter o índice de shards não atribuídos

    $ curl -XGET http://172.16.4.140:9200/_cat/shards
    
  • Instale as ferramentas do curador e use-o para excluir o índice

    $ curator --host 172.16.4.140 delete indices --older-than 1 \
           --timestring '%Y.%m.%d' --time-unit days --prefix logstash
    

    NOTA: No meu caso, o índice é logstash do dia 21-04-2016

  • Em seguida, verifique os fragmentos novamente, todos os fragmentos não atribuídos desaparecem!

1
@ Sim, muito obrigado pela sua edição para a minha resposta. Eu sou muito pobre em edição, prestarei mais atenção a isso.
User3391471 27/05

Para mim, foi:curator_cli --host 127.0.0.1 delete_indices --filter_list '[{"filtertype":"pattern","kind":"prefix","value":"logstash-"}]'
Gaui 20/02

2

Eu também conheço essa situação e finalmente a consertei.

Em primeiro lugar, descreverei minha situação. Eu tenho dois nós no cluster do ElasticSearch, eles podem se encontrar, mas quando eu criei um índice com as configurações "number_of_replicas": 2 , "number_of_shards": 5, o ES mostra sinal amarelo e unassigned_shards é 5.

O problema ocorre porque o valor de number_of_replicas , quando defino seu valor com 1 , está tudo bem.


4
O número de réplicas sempre deve ser N-1, o número de nós que você possui. Portanto, no seu cenário com 2 nós, 1 dos nós contém o shard primário, enquanto o outro nó possui a réplica, portanto, seu número de réplicas deve ser definido como 1. N = 2, N - 1 = 1.
slm

1

No meu caso, um nó antigo com compartilhamentos antigos estava ingressando no cluster; portanto, tivemos que desligar o nó antigo e excluir os índices com shards não atribuídos.


1

Tentei várias das sugestões acima e infelizmente nenhuma delas funcionou. Temos um índice "Log" em nosso ambiente inferior, onde os aplicativos escrevem seus erros. É um cluster de nó único. O que o resolveu para mim foi verificar o arquivo de configuração YML para o nó e ver que ele ainda tinha a configuração padrão "gateway.expected_nodes: 2". Isso substituiu quaisquer outras configurações que tivéssemos. Sempre que criamos um índice nesse nó, ele tentava espalhar 3 dos 5 shards para o segundo nó fantasma. Portanto, eles pareceriam não atribuídos e nunca poderiam ser movidos para o primeiro e único nó.

A solução estava editando a configuração, alterando a configuração "gateway.expected_nodes" para 1, para que deixasse de procurar seu irmão nunca encontrado no cluster e reinicie a instância do serviço Elastic. Além disso, tive que excluir o índice e criar um novo. Após criar o índice, todos os shards apareceram no primeiro e único nó e nenhum foi atribuído.

# Set how many nodes are expected in this cluster. Once these N nodes
# are up (and recover_after_nodes is met), begin recovery process immediately
# (without waiting for recover_after_time to expire):
#
# gateway.expected_nodes: 2
gateway.expected_nodes: 1

1

Para mim, isso foi resolvido executando isso no console do desenvolvedor: "POST / _cluster / reroute? Retry_failed"

.....

Comecei olhando a lista de índices para ver quais índices estavam vermelhos e depois corri

"get /_cat/shards?h=[INDEXNAME},shard,prirep,state,unassigned.reason"

e viu que havia fragmentos presos no estado ALLOCATION_FAILED; portanto, executar a nova tentativa acima fez com que tentassem novamente a alocação.


A partir da versão 5.6.3 do comand deve ser get /_cat/shards/[INDEXNAME]?h=,shard,prirep,state,unassigned.reason
fasantos

0

Pode ajudar, mas tive esse problema ao tentar executar o ES no modo incorporado. A correção foi feita para garantir que o Nó tivesse o conjunto local (verdadeiro).



0

Encontrei exatamente o mesmo problema. Isso pode ser evitado configurando temporariamente a alocação de shard como false antes de reiniciar o elasticsearch, mas isso não corrige os shards não atribuídos se eles já estiverem lá.

No meu caso, foi causado pela falta de espaço livre em disco no nó de dados. Os shards não atribuídos ainda estavam no nó de dados após a reinicialização, mas não foram reconhecidos pelo mestre.

Apenas a limpeza de um dos nós do disco iniciou o processo de replicação para mim. Este é um processo bastante lento porque todos os dados precisam ser copiados de um nó de dados para o outro.


0

Tentei excluir shards não atribuídos ou atribuí-los manualmente a um nó de dados específico. Não funcionou porque os fragmentos não atribuídos continuavam aparecendo e o status de saúde era "vermelho" repetidamente. Então notei que um dos nós de dados estava preso no estado "reiniciar". Eu reduzo o número de nós de dados, matei. O problema não é mais reproduzível.


0

Eu tinha dois índices com fragmentos não atribuídos que não pareciam autocura. Acabei resolvendo isso adicionando temporariamente um nó de dados extra [1] . Depois que os índices ficaram saudáveis ​​e tudo se estabilizou em verde, removi o nó extra e o sistema foi capaz de reequilibrar (novamente) e estabelecer um estado saudável.

É uma boa idéia evitar matar vários nós de dados de uma só vez (foi assim que entrei nesse estado). Provavelmente, não consegui preservar cópias / réplicas de pelo menos um dos fragmentos. Felizmente, o Kubernetes manteve o armazenamento em disco e o reutilizou quando eu reiniciei o nó de dados.


... Algum tempo se passou ...

Bem, desta vez, apenas adicionar um nó não parecia estar funcionando (depois de esperar vários minutos para que algo acontecesse), então comecei a bisbilhotar na API REST.

GET /_cluster/allocation/explain

Isso mostrou meu novo nó com "decision": "YES".

A propósito, todos os nós pré-existentes eram "decision": "NO"devidos a "the node is above the low watermark cluster setting". Portanto, esse foi provavelmente um caso diferente do que eu havia abordado anteriormente.

Então eu fiz o seguinte POST simples [2] sem corpo , o que impulsionou as coisas ...

POST /_cluster/reroute

Outras notas:


[1] Muito fácil de fazer no Kubernetes, se você tiver espaço suficiente: basta dimensionar o conjunto estável através do painel.

[2] Usando a interface "Dev Tools" do Kibana, não precisei me preocupar com shells SSH / exec.


0

Acabei de aumentar o

"index.number_of_replicas"

em 1 (aguarde até que os nós sejam sincronizados) e diminua em 1 depois, o que efetivamente remove os shards não atribuídos e o cluster fica verde novamente sem o risco de perder dados.

Acredito que existem maneiras melhores, mas isso é mais fácil para mim.

Espero que isto ajude.


0

Ao lidar com shards corrompidos, você pode definir o fator de replicação como 0 e, em seguida, retorná-lo ao valor original. Isso deve esclarecer a maioria, senão todos os shards corrompidos, e realocar as novas réplicas no cluster.

Configurando índices com réplicas não atribuídas para usar um fator de replicação 0:

curl -XGET http://localhost:9200/_cat/shards |\
  grep UNASSIGNED | grep ' r ' |\
  awk '{print $1}' |\
  xargs -I {} curl -XPUT http://localhost:9200/{}/_settings -H "Content-Type: application/json" \
  -d '{ "index":{ "number_of_replicas": 0}}'

Configurando-os de volta para 1:

curl -XGET http://localhost:9200/_cat/shards |\
  awk '{print $1}' |\
  xargs -I {} curl -XPUT http://localhost:9200/{}/_settings -H "Content-Type: application/json" \
  -d '{ "index":{ "number_of_replicas": 1}}'

Nota: Não execute isso se você tiver fatores de replicação diferentes para índices diferentes. Isso codificaria o fator de replicação para todos os índices para 1.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.