ElasticSearch: неназначенные осколки, как исправить?

у меня есть кластер ES с 4 узлами:

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

мне пришлось перезапустить search03, и когда он вернулся, он присоединился к кластеру без проблем, но оставил 7 неназначенных осколков.

{
  "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
}

Теперь мой кластер находится в желтом состоянии. Как лучше всего решить эту проблему?

  • удалить (отменить) черепки?
  • переместить осколки на другой узел?
  • выделить осколки узлу?
  • обновление 'number_of_replicas' до 2?
  • что-то совсем другое?

интересно, что когда был добавлен новый индекс, этот узел начал работать над ним и играл хорошо с остальной частью кластера, он просто оставил неназначенные осколки.

следуйте за вопросом: я делаю что-то неправильно, чтобы это произошло в первую очередь? У меня нет большой уверенности в кластере, который ведет себя таким образом при перезапуске узла.

Примечание: если по какой-то причине вы используете кластер с одним узлом, вам может просто потребоваться сделать следующее:

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

19 ответов


по умолчанию Elasticsearch будет повторно назначать осколки узлам динамически. Однако, если вы отключили выделение осколков (возможно, вы сделали rolling restart и забыл включить его), вы можете повторно включить выделение сегментов.

# 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"
    }
}'

Elasticsearch затем переназначит осколки как обычно. Это может быть медленно, рассмотреть повышение indices.recovery.max_bytes_per_sec и cluster.routing.allocation.node_concurrent_recoveries чтобы его ускорить.

если вы все еще видите проблемы, что-то еще, вероятно, не так, поэтому посмотрите в свой Журналы Elasticsearch для ошибок. Если вы видите EsRejectedExecutionException ваши пулы потоков может быть слишком мал.

наконец, вы можете явно переназначить осколок узлу с помощью перенаправить API.

# 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
        }
    }]
}'

хорошо, я решил это с некоторой помощью поддержки ES. Выполните следующую команду API на всех узлах (или узлах, которые вы считаете причиной проблемы):

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

здесь <index> - это индекс, который вы считаете виновником. Если вы понятия не имеете, просто запустите это на всех узлах:

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

Я также добавил эту строку в свою конфигурацию yml, и с тех пор любые перезагрузки сервера/службы были без проблем. Осколки перераспределяются обратно немедленно.

FWIW, чтобы ответить на часто задаваемый вопрос, установите MAX_HEAP_SIZE в 30G, если ваша машина не имеет меньше 60G ОЗУ, и в этом случае установите его в половину доступной памяти.


этот маленький скрипт bash будет переназначать грубую силу, вы можете потерять данные.

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

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

единственное, что сработало для меня, это изменение number_of_replicas (у меня было 2 реплики, поэтому я изменил его на 1, а затем вернулся к 2).

первый:

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

затем:

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

(Я уже asnwered это в этот вопрос)


Elasticsearch автоматически выделяет осколки, если в приведенной ниже конфигурации установлено значение all. Эта конфигурация может быть установлена с помощью rest api, а также кластера.маршрутизирующий.распределение.включить: все

если даже после применения приведенной ниже конфигурации es не может назначить осколки автоматически, то вы должны принудительно назначить осколки самостоятельно. ES официальная ссылка для этого

Я написал сценарий, чтобы принудительно назначить все неназначенные осколки через группа.

ниже массив содержит список узлов, среди которых вы хотите сбалансировать неназначенные Черепков

#!/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 }'))
    SHARD=$(echo $line | (awk '{print }'))
    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

Я застрял сегодня с той же проблемой распределения осколков. Сценарий W. Andrew Loe III предложенный в его ответе не сработал для меня, поэтому я немного изменил его, и он, наконец, сработал:

#!/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

теперь я не гуру Bash, но сценарий действительно работал для моего случая. Обратите внимание, что вам нужно будет указать соответствующие значения для переменных "ES_HOST" и "NODE".


в моем случае была достигнута верхняя граница пространства на жестком диске.

посмотрите на эту статью: https://www.elastic.co/guide/en/elasticsearch/reference/current/disk-allocator.html

в принципе, я побежал:

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

Так что он выделит, если 95% пространства на жестком диске используется; и он проверяет каждую минуту.


может быть, это кому-то помогает, Но у меня была та же проблема, и это было из-за отсутствия места для хранения, вызванного слишком большим журналом.

надеюсь, это поможет кому-то! :)


У меня была та же проблема, но основной причиной была разница в номерах версий (1.4.2 на двух узлах (с проблемами) и 1.4.4 на двух узлах (ok)). Первый и второй ответы (настройка " index.маршрутизирующий.распределение.disable_allocation "в false и установка" кластера.маршрутизирующий.распределение.включить" на "все") не получилось.

однако ответ @Wilfred Hughes (настройка " cluster.маршрутизирующий.распределение.enable " to " all " using transient) дал мне ошибку со следующим заявление:

[нет (версия целевого узла [1.4.2] старше версии исходного узла [1.4.4])]

после обновления старых узлов до 1.4.4 эти узлы начали resnc с другими хорошими узлами.


у меня тоже была эта проблема, и я нашел простой способ ее решить.

  • получить индекс неназначенных осколков

    $ curl -XGET http://172.16.4.140:9200/_cat/shards
    
  • установите инструменты куратора и используйте его для удаления индекса

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

    Примечание: в моем случае, индекс logstash дня 2016-04-21

  • затем проверьте осколки снова, все неназначенные осколки уходят!

в моем случае, когда я создаю новый индекс по умолчанию number_of_replicas устанавливается как 1. И количество узлов в моем кластере было только одним, поэтому не было дополнительного узла для создания реплики, поэтому здоровье становилось желтым. Поэтому, когда я создал индекс с настройки свойства и выберите number_of_replicas as 0. Тогда это сработало нормально. Надеюсь, это поможет.

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

Я также встречаю эту ситуацию и, наконец, исправил ее.

во-первых, я опишу мою ситуацию. У меня есть два узла в кластере ElasticSearch, они могут найти друг друга, но когда я создал индекс с настройками "number_of_replicas" : 2, "number_of_shards": 5, ES показывают желтый сигнал, а unassigned_shards-5.

проблема возникает из-за значения number_of_replicas, когда я устанавливаю его значение с 1 все штраф.


в моем случае старый узел со старыми акциями присоединялся к кластеру, поэтому нам пришлось отключить старый узел и удалить индексы с неназначенными осколками.


для меня это было решено, запустив это из консоли разработчика: "POST /_cluster/reroute?retry_failed"

.....

Я начал с просмотра списка индексов, чтобы увидеть, какие индексы были красными, а затем побежал

"получить /_cat/Черепков?h=[INDEXNAME], осколок,prirep,состояние, неназначенный.причина"

и увидел, что у него есть осколки, застрявшие в состоянии ALLOCATION_FAILED, поэтому запуск повторной попытки выше заставил их повторно попробовать распределение.


может помочь, но у меня была эта проблема при попытке запустить ES во встроенном режиме. Fix должен был убедиться, что узел имеет локальный (true) набор.


еще одна возможная причина для неназначенных осколков заключается в том, что в кластере выполняется более одной версии двоичного файла Elasticsearch.

репликация осколков из более последней версии в предыдущую версии не будут работать

Это может быть основной причиной для неназначенных осколков.

Эластичная Документация-Процесс Обновления Прокатки


Я столкнулся с точно такой же проблемой. Это можно предотвратить, временно установив распределение осколков в false перед перезапуском elasticsearch, но это не исправляет неназначенные осколки, если они уже есть.

в моем случае это было вызвано отсутствием свободного места на диске на узле данных. Неназначенные фрагменты, где все еще на узле данных после перезапуска, но они не распознаются мастером.

просто очистка 1 узлов с диска получила для меня начался процесс репликации. Это довольно медленный процесс, потому что все данные должны быть скопированы данные из 1 узла к другому.


я попробовал несколько предложений выше и, к сожалению, ни один из них не работал. У нас есть индекс" Log " в нашей нижней среде, где приложения пишут свои ошибки. Это кластер с одним узлом. То, что решило это для меня, проверяло файл конфигурации YML для узла и видело, что у него все еще есть настройка по умолчанию "gateway.expected_nodes: 2". Это перекрывало все остальные настройки, которые у нас были. Всякий раз, когда мы создадим индекс на этом узле, он попытается распространить 3 из 5 осколков на Фантом 2-го узла. Поэтому они будут отображаться как неназначенные, и они никогда не могут быть перемещены в 1-й и единственный узел.

решением было редактирование конфигурации, изменение параметра " gateway.expected_nodes " до 1, поэтому он перестанет искать своего брата, который никогда не будет найден в кластере, и перезапустит экземпляр службы Elastic. Кроме того, мне пришлось удалить индекс и создать новый. После создания индекса все осколки появились на 1-м и единственном узле, и ни один из них не был неназначенный.

# 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

Я попытался удалить неназначенные фрагменты или вручную назначить их конкретному узлу данных. Это не сработало, потому что неназначенные осколки продолжали появляться, а состояние здоровья было "красным" снова и снова. Затем я заметил, что один из узлов данных застрял в состоянии "перезапуска". Я уменьшил количество узлов данных, убил его. Проблема больше не воспроизводима.