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
}

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

  • Удалить (отменить) осколки?
  • Переместите осколки на другой node?
  • Выделите осколки до node?
  • Обновить 'number_of_replicas' до 2?
  • Что-то еще полностью?

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

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

ПРИМЕЧАНИЕ. Если вы используете какой-то один кластер node по какой-либо причине, вам может потребоваться сделать следующее:

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

Ответ 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}'

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

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

Рекомендации

Ответ 2

По умолчанию Elasticsearch будет динамически переназначать осколки узлов. Однако, если вы отключили выделение 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"
    }
}'

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

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

Наконец, вы можете явно переназначить осколок на node с помощью перенаправления 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
        }
    }]
}'

Ответ 3

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

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

Ответ 4

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

Во-первых:

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

Тогда:

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

(Я уже ответил на этот вопрос)

Ответ 5

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

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

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

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

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

Ответ 6

Я застрял сегодня с той же проблемой распределения осколков. script, что 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, но script действительно работал для моего дела. Обратите внимание, что вам нужно указать соответствующие значения для переменных "ES_HOST" и "NODE".

Ответ 7

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

Посмотрите на эту статью: 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"
  }
}

Таким образом, он будет выделять, если используется < 90% пространства на жестком диске, и переместить осколок на другую машину в кластере, если > 95% используемое место на жестком диске; и он проверяет каждую минуту.

Ответ 8

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

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

Ответ 9

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

Однако ответ @Wilfred Hughes (установка "cluster.routing.allocation.enable" на "all" с использованием переходного процесса) вызвал ошибку со следующим утверждением:

[НЕТ (цель node версия [1.4.2] старше исходной версии node[1.4.4])]

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

Ответ 10

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

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

Ответ 11

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

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

    $ 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

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

Ответ 12

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

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

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

Ответ 13

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

Ответ 14

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

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

# 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

Ответ 15

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

.....

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

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

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

Ответ 16

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

Ответ 17

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

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

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

Эластичная документация - процесс обновления ролика

Ответ 18

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

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

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

Ответ 19

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

Ответ 20

У меня было два индекса с неназначенными осколками, которые, казалось, не излечивали себя. В конце концов я решил эту проблему, временно добавив дополнительный узел данных [1]. После того, как индексы стали здоровыми, и все стабилизировалось до зеленого, я удалил лишний узел, и система смогла восстановить баланс (снова) и установить здоровое состояние.

Это хорошая идея, чтобы не убивать сразу несколько узлов данных (именно так я попал в это состояние). Вероятно, мне не удалось сохранить какие-либо копии/реплики хотя бы для одного из осколков. К счастью, Kubernetes сохранил дисковое хранилище и использовал его снова, когда я перезапустил узел данных.


... прошло некоторое время...

Что ж, на этот раз простое добавление узла, похоже, не работало (после ожидания нескольких минут, пока что-то произошло), поэтому я начал ковыряться в REST API.

GET /_cluster/allocation/explain

Это показал мой новый узел с "decision": "YES".

Кстати, все ранее существовавшие узлы имели "decision": "NO" из-за того, что "the node is above the low watermark cluster setting". Так что это, вероятно, был другой случай, чем тот, который я рассматривал ранее.

Затем я сделал следующий простой POST [2] без тела, который включил передачу...

POST /_cluster/reroute

Другие заметки:


[1] Это довольно легко сделать в Кубернетесе, если у вас достаточно запаса: просто масштабируйте набор состояний с помощью панели инструментов.

[2] Используя интерфейс Kibana "Dev Tools", мне не нужно было работать с SSH/exec-оболочками.

Ответ 21

Я только что увеличил

"index.number_of_replicas"

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

Я верю, что есть лучшие способы, но для меня это проще.

Надеюсь это поможет.

Ответ 22

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

Настройка индексов с неназначенными репликами для использования коэффициента репликации 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}}'

Установка их обратно на 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}}'

Примечание: Не запускайте это, если у вас разные коэффициенты репликации для разных индексов. Это жестко закодировало бы коэффициент репликации для всех индексов в 1.