Зелёный статус для одиночного ElasticSearch
- Когда мы собеседуем системных администраторов и видим в их резюме упоминание ElasticSearch,
мы обязательно задаём им вопрос «какого цвета будет одиночный сервер?»
- Примерно половина соискателей не понимает его смысла и на этом наше знакомство с ними, как правило, заканчивается
(потому что их владение остальными указанными в резюме терминами обычно находится на аналогичном уровне).
Оставшейся половине мы задаём два вопроса:
- Почему он жёлтый,
- и как превратить его в зелёный, не создавая кластер?
Цвет означает состояние сервера:
- Зелёный — всё хорошо.
- Жёлтый — сервер правильно обрабатывает все запросы на чтение/запись, но есть внутренние проблемы, которые необходимо исправить.
- Красный — всё плохо.
Как увидеть цвет сервера?
curl '127.0.0.1:9200/_cluster/health?pretty=true'
Пример ответа:
{
"cluster_name" : "elasticsearch",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 1880,
"active_shards" : 1880,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 1680,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 52.80898876404494
}
Почему отдельный сервер будет по умолчанию жёлтым?
- Потому что ElasticSearch является отказоустойчивой системой хранения данных, которая расчитана для запуска не на одном сервере, а на группе
(кластере) из нескольких связанных серверов (узлов, “nodes”).
- В частности, ElasticSearch подразумевает, что при отказе одного узла система должна сохранять полную работоспособность.
- Для этого система должна состоять из нескольких серверов (минимум — двух, желательно — трёх для предотвращения split brain),
и каждая порция данных (т.н. “shard” в терминологии ES) должна храниться в нескольких экземплярах на разных серверах.
- Один из этих экземпляров ES будет считать первичным (“master shard”), остальные копиями первичного (“replica shards”).
- В системе из одного сервера ES хранит на нём все “primary shards”, но создавать “replica shards” такой системе будет
негде.
- Поэтому статус в приведённом примере является жёлтым из-за ненулевого значения “unassigned_shards”, которое примерно равно
“active_shards”.
- Небольшая разница между количеством активных и неразмещённых шардов обусловлена тем, что часть служебных индексов является локальной для
каждого узла, то есть не должна иметь реплик и не приводит к появлению unassigned shards.
- Подробнее о том, что такое шарды, зачем они нужны, и какое место занимают между документами и индексами: https://stackoverflow.com/a/49892584/2743554.
Как сделать одиночный сервер зелёным?
- Сначала узнаем, какие шарды система не сумела разместить:
curl -sS -XGET '127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason' | grep UNASSIGNED
Теперь посмотрим, к каким индексам они относятся:
curl -sS -XGET '127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason' | awk '/UNASSIGNED/ { print $1 }'
После этого поменяем настройки индексов — уменьшим количество реплик (так называемый Replication Factor) до нуля:
curl -sS -XGET '127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason' | awk '/UNASSIGNED/ { print $1 }' |
while read idx; do
curl -XPUT "localhost:9200/$idx/_settings" -H 'Content-Type: application/json' -d '{ "index": { "number_of_replicas": 0 } }'
done
И проверим результат:
{
"cluster_name" : "elasticsearch",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 1880,
"active_shards" : 1880,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
Почему в полночь карета превратится в тыкву сервер снова станет жёлтым?
- Потому что в ES принято каждые сутки автоматически создавать новый индекс с именем вида “basename-yyyy.mm.dd” из шаблона.
- Поэтому Replication Factor необходимо уменьшить до нуля не только в существующих индексах, но и в шаблонах, из которых будут создаваться
новые индексы.
- Это делается так:
curl -XPUT "127.0.0.1:9200/_template/all?pretty=true" -H 'Content-Type: application/json' -d \
'{ "template" : "*" , "settings": { "number_of_replicas": 0 } }'
После этого постоянный статус одиночного сервера станет зелёным, а жёлтый превратится из «фонового шума» в надёжный показатель
проблем, действительно требующих исправления.