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