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