Перейти к основному содержимому
Версия: 6.0

Настройка Disk Watermark

Общая информация

Механизм Disk Watermark представляет собой трехуровневую систему защиты, предназначенную для:

  • превентивного ограничения записи данных на узел
  • инициации перераспределения шардов
  • полной блокировки записи в критических ситуациях

Цель механизма - сохранение целостности существующих индексов при исчерпании дискового пространства.


Архитектура механизма

Настройки cluster.routing.allocation.disk.watermark.* задаются на уровне всего кластера. Это единое, глобальное правило, которое хранится в настройках кластера (cluster state) и применяется одинаково ко всем узлам data. Вы не можете задать разный процент заполнения для разных узлов с помощью этих параметров.

Проверка и реакция происходят на каждом узле независимо. Каждый узел, получив единую настройку кластера, непрерывно сравнивает это значение с состоянием своего локального диска с данными. Решение о превышении порога и соответствующие действия (отказ от размещения новых шардов, перемещений шардов, переход в read-only) принимаются узлом индивидуально, на основе его собственных показателей.

Все запросы выполняются через Консоль разработчика (Навигационное меню - Параметры системы - Консоль разработчика), или через curl-запрос.

curl -k -X PUT "https://<opensearch_host>:9200/_cluster/settings" \
-H 'Content-Type: application/json' \
-u 'admin:admin' \
-d '{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "80%",
"cluster.routing.allocation.disk.watermark.high": "85%",
"cluster.routing.allocation.disk.watermark.flood_stage": "90%"
}
}'

Трехуровневая система защиты кластера от переполнения дисков

Параметр: cluster.routing.allocation.disk.watermark.low

Значение по умолчанию: 85%

Поведение:

  • узел исключается из кандидатов на размещение новых шардов
  • мастер-узел прекращает назначение новых индексов и реплик на данный узел
  • существующая запись продолжается

Назначение: Предупреждение администратора о приближении критического уровня заполнения диска.

Проверить текущие настройки кластера:

GET _cluster/settings?include_defaults=true

Применить требуемые настройки disk watermark:

PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": " 85%",
"cluster.routing.allocation.disk.watermark.high": " 90%",
"cluster.routing.allocation.disk.watermark.flood_stage": " 95%"
}
}

Риски использования пороговых значений, заданных в процентах

Использование процентных значений по умолчанию (85%, 90%, 95%) сопряжено с определенными рисками, которые обусловлены тем, что относительные величины не отражают абсолютный объем свободного пространства, остающегося доступным на устройстве в момент срабатывания защитных механизмов. Данное несоответствие способно привести к нештатной деградации шардов еще до достижения расчетного порогового значения.

Пример:

Сервер с Smart Monitor c разделом емкостью 2 ТБ.

  • при пороге flood_stage, равном 95%, блокировка записи активируется только после того, как объем нераспределенного пространства сократится до 100 ГБ
  • при этом на узле может располагаться шард размером, например, 50 ГБ, для которого планируется операция принудительного слияния сегментов (force merge). В ходе выполнения данной операции библиотека Apache Lucene производит временное резервирование дискового пространства, сопоставимого по объему с размером сливаемого шарда
  • вследствие описанного несоответствия возникает риск аварийного завершения процесса записи с ошибкой No space left on device и, как следствие, повреждения шарда до того момента, как датчик заполнения диска зафиксирует достижение 95% и инициирует защитную блокировку

Рекомендация по конфигурированию

Для разделов большой емкости целесообразно использовать абсолютные пороговые значения (Mb, Gb). Данный подход гарантирует наличие заранее рассчитанного запаса свободного пространства, достаточного для корректного выполнения ресурсоемких фоновых операций над шардами большого размера.

Пример конфигурации с абсолютными значениями:

PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "200gb",
"cluster.routing.allocation.disk.watermark.high": "100gb",
"cluster.routing.allocation.disk.watermark.flood_stage": "50gb"
}
}

При установке абсолютных значений необходимо соблюдать следующее условие: значение low-порога не должно превышать физическую емкость наименьшего дискового устройства в составе кластера. Несоблюдение данного условия приведет к тому, что узел с диском минимального размера будет исключен из процесса аллокации и полностью прекратит прием шардов.

примечание

В кластере с дисками разного объема (например, 500 ГБ и 3 ТБ) настройка порогов в процентном отношении может быть критична: 10% на 500 ГБ — это 50 ГБ, а 10% на 3 ТБ — это 300 ГБ. Балансировка будет работать непредсказуемо. Рекомендуется используйте абсолютные значения. В целом, в кластере Smart Monitor рекомендуется использовать data-узлы c одинаковыми размерами дискового хранилища.

Разница между transient и persistent в настройках кластера Smart Monitor

При настройке кластера возможно использовать следующие параметры:

transient (временные настройки):

  • применяются немедленно, но не сохраняются после перезапуска кластера
  • имеют приоритет над persistent: если один и тот же параметр задан в обеих секциях, действует значение из transient
  • подходят для оперативных изменений, тестирования, временного решения проблем
  • сбрасываются до значений по умолчанию или до persistent после рестарта узлов

persistent (постоянные настройки):

  • сохраняются в индексе кластера и сохраняются после рестарта узлов
  • действуют постоянно, пока не будут явно изменены или сброшены (установлены в null)
  • применяются сразу, но могут быть переопределены transient-настройками

Действия при возникновении инцидента

При срабатывание flood_stage кластер переводит индексов в режим read-only. Главное, что следует учитывать при устранении проблемы – снятие блокировки не происходит автоматически при расширении диска или удалении данных.

1. Диагностика

Проверить состояние кластера:

GET _cluster/health?pretty

Возможные значения параметра status:

  • green — все шарды распределены
  • yellow — часть реплик не распределена
  • red — часть primary-шардов не распределена, данные недоступны

Проверить состояние дисков и шардов на узлах:

GET _cat/allocation?v&h=node,disk.used_percent,disk.used,disk.avail,disk.total,shards

Пример вывода команды:

node        	  disk.used   disk.avail    disk.total   shards
smos-node-02 251gb 725gb 976gb 1953
smos-node-00 276.4gb 671.4gb 947.9gb 1952

Найти индексы, занимающие больше всего места:

GET _cat/indices?v&h=index,store.size&s=store.size:desc

Если данные индексов не критичны, их можно удалить:

DELETE /<index-name>
DELETE /sm_servers_hosts_uptime-000405
DELETE /sm_servers_hosts_uptime-2025*

2. Освобождение физического пространства

Первоочередная задача — устранить корневую причину: либо физически расширить дисковое пространство (через LVM, облачный диск), либо очистить старые индексы/документы, чтобы снизить заполненность диска ниже порога flood_stage.

Временная мера, если нет возможности немедленно расширить диск:

Поднять порог flood_stage через transient-настройки (сбросятся после перезапуска кластера):

PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.disk.watermark.flood_stage": "98%"
}
}

Но при большом потоке данных и больших размерах шардов, это не принесет пользы.

3. Принудительное снятие блокировки

Выполнить запрос для снятия флага read_only_allow_delete со всех индексов кластера:

PUT */_settings
{
"index.blocks.read_only_allow_delete": null
}

Для снятия блокировки с конкретного индекса:

PUT /<index-name>/_settings
{
"index.blocks.read_only_allow_delete": null
}

Проверить наличие заблокированных индексов:

GET _all/_settings?filter_path=**.blocks*

В выводе команды у заблокированного индекса присутствует параметр:

"blocks": {
"read_only_allow_delete": "true"
}

4. Восстановление зависших шардов

После снятия блокировки повторно проверить состояние кластера:

GET _cluster/health?pretty

Восстановление кластера может занять значительный промежуток времени.

Если статус остается red или yellow, а количество неназначенных шардов (unassigned shards) не уменьшается или достигло определенного значения и не изменяется – это означает, что попытки аллокации завершились с ошибками.

Проверить состояние нераспределенных шардов:

GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason&s=state

Проверить состояние аллокации:

GET _cluster/allocation/explain?pretty 

Для диагностики шарда конкретного индекса <index-name>:

GET _cluster/allocation/explain
{
"index": "<index-name>",
"shard": 0,
"primary": true
}

Запустить принудительное перераспределение. Выполняет одну попытку, при необходимости можно повторить команду:

POST _cluster/reroute?retry_failed=true

5. Ускорение восстановления (Опционально)

По умолчанию узлы отчитываются о занятости диска раз в 30 секунд. Чтобы мастер-узел быстрее "увидел", что место появилось, и снял ограничение с узла в оперативной памяти, можно временно уменьшить интервал:

PUT _cluster/settings
{
"persistent": {
"cluster.info.update.interval": "15s"
}
}

Дополнительно можно увеличить лимиты на одновременные восстановления шардов:

PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.node_concurrent_incoming_recoveries": 4,
"cluster.routing.allocation.node_concurrent_outgoing_recoveries": 4,
"indices.recovery.max_bytes_per_sec": "150mb"
}
}

После завершения восстановительных работ обязательно вернуть значения по умолчанию, чтобы не создавать избыточную нагрузку на кластер:

PUT _cluster/settings
{
"transient": {
"cluster.info.update.interval": null,
"cluster.routing.allocation.node_concurrent_incoming_recoveries": null,
"cluster.routing.allocation.node_concurrent_outgoing_recoveries": null,
"indices.recovery.max_bytes_per_sec": null
}
}

Сброс параметров disk watermark на значения по умолчанию

Если конфигурация была изменена неудачно, всегда можно откатиться на значения по умолчанию.

Поскольку вы используете persistent, настройки сохранятся даже после перезапуска кластера. Однако, если до этого вы меняли их через transient, то у transient приоритет выше — и сброс persistent в null не даст видимого эффекта, пока действуют transient-значения.

PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": null,
"cluster.routing.allocation.disk.watermark.high": null,
"cluster.routing.allocation.disk.watermark.flood_stage": null
},
"transient": {
"cluster.routing.allocation.disk.watermark.low": null,
"cluster.routing.allocation.disk.watermark.high": null,
"cluster.routing.allocation.disk.watermark.flood_stage": null
}
}

Как связаны cluster.routing.rebalance.enable и watermark

Параметр cluster.routing.rebalance.enable контролирует:

  • плановую балансировку — равномерное распределение шардов по узлам для оптимальной производительности
  • срабатывает при добавлении/удалении узлов, изменении весов узлов
  • не влияет на аварийные механизмы защиты дисков

Если установить cluster.routing.rebalance.enable: none, система все равно будет перемещать шарды с заполненного диска при превышении high watermark. Этот параметр не является способом предотвратить перемещение шардов — для этого потребовалось бы изменить сами пороги (watermark.high) или отключить мониторинг диска через cluster.routing.allocation.disk.threshold_enabled: false (чего делать категорически не рекомендуется).