ElasticSearch: Непризначені осколки, як виправити?


165

У мене кластер 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
    }
}'

Відповіді:


117

За замовчуванням Elasticsearch динамічно повторно призначить фрагменти вузлам. Однак якщо ви відключили розподіл фрагментів (можливо, ви перезапустили перегляд і забули повторно включити його), ви можете повторно включити розподіл фрагментів.

# 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"
    }
}'

Еластичний пошук потім присвоює клаптики як звичайні. Це може бути повільним, враховуйте підвищення 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
        }
    }]
}'

3
Коли я це зробив, я отримав: { "error" : "ElasticsearchIllegalArgumentException[[allocate] failed to find [logstash-2015.01.05][1] on the list of unassigned shards]", "status" : 400 } Хоча я бачу, що осколок є одним з нерозподілених в ES-Head
wjimenez5271

Між іншим, працювали й інші осколки, які були зафіксовані як нерозподілені, а потім решта виправились.
wjimenez5271

це чудова порада.
Йозеф

1
З моменту випуску 5.0 команда «розподілити» змінилася, щоб надати більше опцій - тепер у прикладі вище буде "розподілити_емроти_примірник", опустивши параметр "дозволити_прімар".
jmb

4
вам потрібно додати, -H 'Content-Type: application/json'якщо ви отримаєте помилкуContent-Type header [application/x-www-form-urlencoded] is not supported
luckydonald

57

Гаразд, я вирішив це за допомогою допомоги 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, якщо ваша машина не має менше 60 Гб оперативної пам’яті, і в цьому випадку встановіть її на половину наявної пам’яті.

Список літератури


2
щоб вирішити це у версії 1.1.1, чи слід використовувати cluster.routing.allocation.enable = none?
user3175226

1
Вимкнення виділення більше не зафіксовано там, принаймні, не станом на 20 листопада.

3
Зауважте, що розподіл маршрутизації - це налаштування для кластера, тому не має значення, на який вузол ви надсилаєте команду.
Вілфред Х'юз

Я додав обоє у свій файл es yml. index.routing.allocation.disable_allocation : false cluster.routing.allocation.enable: noneАле все одно проявляються непризначені черепки .. Що може бути причиною?
bagui

1
У версії 6.8 я отримую помилку:{ "type": "illegal_argument_exception", "reason": "unknown setting [index.routing.allocation.disable_allocation] please check that any required plugins are installed, or check the breaking changes documentation for removed settings" } ],
Janac Meena

39

Цей маленький баш-скрипт буде грубо примусово перепризначити, ви можете втратити дані.

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

Працював як шарм. Дякую!
Пауло Пірес

Я отримав цю помилку: <br> {"error": "JsonParseException [Неочікуваний символ r (',' (код 44)): очікуване дійсне значення (число, рядок, масив, об'єкт," true "," false "або 'null') \ n у [Джерело: [B @ 3b1fadfb; рядок: 6, стовпець: 27]] "," статус ": 500} - що мені робити, щоб виправити це
biolinh

Дякую тонну! Це заощадило дорогоцінний час !!
Сатиш

Сценарій {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}
наводить

17

Єдине, що працювало для мене, - це змінити число_of_replicas (у мене було 2 репліки, тому я змінив його на 1, а потім змінив назад на 2).

Перший:

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

Тоді:

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

(Я вже відповідав на це у цьому питанні )


9

Elasticsearch автоматично виділяє осколки, якщо нижче встановлена ​​конфігурація. Цю конфігурацію можна встановити, використовуючи спокійний api, а також cluster.routing.allocation.enable: all

Якщо навіть після застосування конфігурації, наведеної нижче, 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 $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

Цей сценарій не спрацював, тобто після того, як я його запустив, у мене все ще були НЕЗАДАННІ черепки.
Кріс Ф

@ChrisF У рядку1: вам потрібно замінити node1, node2, node3 фактичними іменами вузлів. Ви можете отримати їх за допомогою локального хосту: 9200 / _cat / вузлів.
sidi

6

Я сьогодні затримався з тим же питанням розподілу осколків. Сценарій, запропонований У. Ендрю Лоєм 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".


на жаль, ES5x порушив сумісність: elastic.co/guide/en/elasticsearch/reference/5.1/…
Fawix

2
Для того , щоб скрипт вище для роботи з ES5x замінити allocateз allocate_empty_primaryі замінити \"allow_primary\": trueз\"accept_data_loss\": true
Fawix

Як {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}навіть після застосування пропозиції
Фавікса

6

У моєму випадку було досягнуто верхньої межі місця на жорсткому диску.

Подивіться цю статтю: 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% місця на жорсткому диску; і перевіряється кожні 1 хвилини.


4

Можливо, це комусь допомагає, але у мене виникло те саме питання, і це було через брак місця для зберігання, викликаний тим, що журнал стає занадто великим.

Сподіваюся, це комусь допоможе! :)


4

У моєму випадку, коли я створюю новий індекс, тоді за замовчуванням number_of_replicas встановлюється як 1. А кількість вузлів у моєму кластері була лише одна, тому не було зайвого вузла для створення репліку, тому стан здоров'я став жовтим. Тож коли я створив індекс із властивістю налаштувань і встановив число_of_replicas як 0. Потім він спрацював нормально. Сподіваюся, це допомагає.

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

3

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

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

[НІ (версія цільового вузла [1.4.2] є старшою за версію вихідного вузла [1.4.4])]

Після оновлення старих вузлів до 1.4.4 ці вузли почали відновлюватись з іншими хорошими вузлами.


3

У мене виникло і це питання, і я знайшов простий спосіб вирішити його.

  • Отримайте індекс непризначених черепків

    $ 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
    

    ПРИМІТКА. У моєму випадку індекс - це реєстрація даних 2016-04-21

  • Потім ще раз перевірте черепки, всі непризначені черепки відходять геть!

1
@sim, дуже дякую за вашу редакцію за мою відповідь. Я дуже бідний на редагування, приділяю це більше уваги.
користувач3391471

Для мене це було:curator_cli --host 127.0.0.1 delete_indices --filter_list '[{"filtertype":"pattern","kind":"prefix","value":"logstash-"}]'
Гауї

2

Я також зустрічаюся з цією ситуацією і нарешті її виправляю.

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

Проблема виникає через те, що при значенні number_of_replicas , коли я встановлюю її значення 1 , все нормально.


4
Кількість реплік завжди має бути N-1, а кількість вузлів у вас є. Отже, у вашому сценарії з 2-ма вузлами 1 з вузлів містить первинний фрагмент, тоді як у іншого вузла є репліка, отже, ваша кількість реплік повинна бути встановлена ​​на 1. N = 2, N - 1 = 1.
slm

1

У моєму випадку до кластеру приєднувався старий вузол зі старими поділками, тому нам довелося вимкнути старий вузол та видалити індекси без присвоєних фрагментів.


1

Я спробував кілька запропонованих вище пропозицій, і, на жаль, жодна з них не спрацювала. У нижньому середовищі індекс "Журнал", де програми записують свої помилки. Це кластер з одним вузлом. Для мене це вирішило - перевірити файл конфігурації 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

1

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

.....

Я почав з перегляду списку індексів, щоб побачити, які індекси червоні, а потім запустив

"get /_cat/shards?h= evidenceINDEXNAMESense,shard,prirep,state,unassigned.reason"

і побачив, що в неї розміщені осколки в стані ALLOCATION_FAILED, тож запуск повторної спроби зверху змусив їх повторно спробувати розподіл.


З версії 5.6.3 команда повинна отримати /_cat
shards/ evidenceINDEXNAME

0

Можливо, допоможе, але у мене виникла ця проблема, коли я намагався запустити ES у вбудованому режимі. Виправтеся, щоб переконатися, що у Вузлі встановлено локальний (справжній).


0

Інша можлива причина непризначених фрагментів - це те, що ваш кластер працює більше ніж однією версією двійкового файлу Elasticsearch.

реплікація осколка з більш нової версії до попередньої версії не буде працювати

Це може бути першопричиною непризначених черепків.

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


0

Я зіткнувся з точно таким же питанням. Цього можна запобігти, тимчасово встановивши розподіл осколка на значення false перед перезапуском еластичного пошуку, але це не виправить непризначені фрагменти, якщо вони вже є.

У моєму випадку це було викликано відсутністю вільного місця на диску на вузлі даних. Непризначені фрагменти, які все ще знаходяться у вузлі даних після перезавантаження, але вони там, де майстер не розпізнається.

Щойно очищення 1 диска з диска розпочало процес реплікації для мене. Це досить повільний процес, оскільки всі дані повинні бути скопійовані з одного вузла даних в інший.


0

Я намагався видалити непризначені фрагменти або вручну призначити їх певному вузлу даних. Це не спрацювало, тому що непризначені черепки продовжували з'являтися, а стан здоров'я "червоний" знову і знову. Потім я помітив, що один із вузлів даних застряг у стані «перезавантаження». Я зменшив кількість вузлів даних, вбив. Проблема вже не відтворюється.


0

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

Це гарна ідея уникати вбивства декількох вузлів даних одночасно (саме так я потрапив у цей стан). Ймовірно, мені не вдалося зберегти жодних копій / реплік принаймні однієї з фрагментів. На щастя, Kubernetes зберегла дискове сховище і повторно використовувала його, коли я знову перекомпонувала вузол даних.


... Минув якийсь час ...

Ну, цього разу просто додавання вузла, здавалося, не спрацювало (почекавши кілька хвилин, щоб щось трапилося), тому я почав ковтати в API REST.

GET /_cluster/allocation/explain

Це показав мій новий вузол с "decision": "YES".

До речі, всі раніше існуючі вузли мали "decision": "NO"через "the node is above the low watermark cluster setting". Тож, мабуть, це був інший випадок, ніж той, про який я звертався раніше.

Тоді я зробив наступний простий POST [2] без корпусу , який забивав речі в передачу ...

POST /_cluster/reroute

Інші примітки:


[1] Досить просто зробити це в Kubernetes, якщо у вас є достатня кількість місця для запасів: просто змініть масштабний набір за допомогою приладної панелі.

[2] Використовуючи інтерфейс Kibana "Dev Tools", мені не довелося турбуватися з оболонками SSH / exec.


0

Я тільки спочатку збільшив

"index.number_of_replicas"

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

Я вважаю, що є кращі способи, але мені це простіше.

Сподіваюся, це допомагає.


0

У роботі з пошкодженими черепками ви можете встановити коефіцієнт реплікації 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.