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 132

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 ваши пулы потоков может быть слишком мал.

наконец, вы можете явно переназначить осколок узлу с помощью reroute 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 автоматически выделяет осколки, если ниже конфигурации установлено значение все. Эта конфигурация может быть установлена с помощью API-интерфейс REST, а также кластера.маршрутизирующий.распределение.включить: все

если даже после применения приведенной ниже конфигурации 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

теперь я не какой-то Баш гуру, но сценарий действительно работал для моего случая. Обратите внимание, что вам нужно будет указать соответствующие значения для переменных "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 на двух узлах (ОК)). Первый и второй ответы (установка " индекс.маршрутизирующий.распределение.disable_allocation "to false and setting" кластер.маршрутизирующий.распределение.включить" на "все") не получилось.

тем не менее, ответ @Wilfred Hughes (настройка "cluster.маршрутизирующий.распределение.разрешить" для "всех", используя переходные) дал мне сообщение об ошибке со следующим заявление:

[нет(версия целевого узла [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 как 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], shard,prirep,state, unassigned.причина"

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

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

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

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

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

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

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

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

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

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

решение состояло в редактировании конфигурации, изменении настройки " шлюз.expected_nodes " до 1, поэтому он перестанет искать своего никогда не найденного брата в кластере и перезапустит экземпляр эластичной службы. Кроме того, мне пришлось удалить индекс и создать новый. После создания индекса все осколки появились на 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

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