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.