Настройка 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%"
}
}'
Трехуровневая система защиты кластера от переполнения дисков
- Уровень 1
- Уровень 2
- Уровень 3
Параметр: cluster.routing.allocation.disk.watermark.low
Значение по умолчанию: 85%
Поведение:
- узел исключается из кандидатов на размещение новых шардов
- мастер-узел прекращает назначение новых индексов и реплик на данный узел
- существующая запись продолжается
Назначение: Предупреждение администратора о приближении критического уровня заполнения диска.
Параметр: cluster.routing.allocation.disk.watermark.high
Значение по умолчанию: 90%
Поведение:
- мастер-узел инициирует перемещение шардов с переполненного узла
- при включенной настройке Shard Allocation Awareness учитываются зоны отказа
Критический нюанс: Перемещение возможно только для шардов с репликами. Primary-шарды без реплик не могут быть перемещены.
Риски: Процесс релокации потребляет значительные ресурсы (IOPS, сеть, CPU)
Shard Allocation Awareness (осведомленность о размещении шардов) — это механизм, который гарантирует, что первичный шард и его реплики не окажутся на одном физическом устройстве или в одной зоне отказа.
Как работает механизм релокации при использовании параметра Shard Allocation Awareness.
Если администратор задал, например, cluster.routing.allocation.awareness.attributes: zone, в настройках узлов кластера настроены параметры node.attr.zone: zoneA, node.attr.zone: zoneB то кластер будет обеспечивать, чтобы копии одного шарда находились в разных зонах (zone-a и zone-b). При срабатывании high-порога на узле в zone-a кластер не может просто переместить реплику на другой узел в той же zone-a. Он будет вынужден искать узел в zone-b, соответствующий условиям аллокации. Это может замедлить эвакуацию или сделать ее временно невозможной, если в zone-b недостаточно места.
Параметр: cluster.routing.allocation.disk.watermark.flood_stage
Значение по умолчанию: 95%
Поведение:
- Все индексы с шардами на затронутом узле переводятся в режим
read_only_allow_delete - Запрещены операции, требующие дискового пространства
- Разрешено только удаление данных
Назначение: Предотвращение повреждения существующих шардов при исчерпании дискового пространства.
Блокировка index.blocks.read_only_allow_delete устанавливается непосредственно в метаданные индекса, хранящиеся в состоянии кластера (cluster state). Вследствие этого ограничение записи распространяется на все узлы, содержащие шарды данного индекса, независимо от уровня заполнения их локальных дисков. Таким образом, даже при наличии реплик на исправных узлах, не достигших пороговых значений, запись в индекс будет полностью остановлена до принудительного снятия блокировки администратором.
Проверить текущие настройки кластера:
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 (чего делать категорически не рекомендуется).