Elasticsearch 7.6: настраиваем ILM-политики горячий-тёплый-холодный и экономим 60% места
Elasticsearch 7.6 выводит ILM и data tiers в GA. Настраиваем hot-warm-cold на клиентском ELK-кластере: NVMe на 7 дней, SATA на 30, объектное хранилище для архива.
Elasticsearch 7.6: ILM (Index Lifecycle Management) переходит в GA, data tiers hot-warm-cold, улучшенный EQL для задач безопасности
Elasticsearch 7.6 вышел несколько дней назад, и главное для нас в этом релизе - не EQL для безопасности, хотя его доработки приятны. Главное - ILM (Index Lifecycle Management) официально в GA. Мы давно использовали его в бета-статусе, но теперь есть повод переосмыслить конфигурацию и сделать всё по-человечески. Клиентский ELK-кластер в managed-сопровождении как раз созрел для этой работы.
Предыстория простая: кластер хранил логи бессрочно на одном типе дисков, индексы копились, место заканчивалось. Типичная история для ELK, который «поставили и забыли».
Что такое data tiers в 7.6
До 7.x управление жизненным циклом индексов делалось через атрибуты нод и ILM-политики, которые двигали шарды на основе кастомных тегов. Работало, но требовало ручной разметки каждой ноды. В 7.6 ILM вышел в GA; разметка нод по тирам по-прежнему делается через кастомные атрибуты (node.attr.data: hot/warm/cold), но теперь ILM-API стабилен и можно строить на нём продакшн-конфигурацию без оглядки на бета-оговорки.
Для нас это значит: можно настроить один раз и не возвращаться к вопросу «а правильно ли разметили ноды».
Топология кластера
Под проект у нас три группы нод:
- Hot - две ноды с NVMe, высокая IOPS, сюда падают все новые индексы.
- Warm - три ноды с SATA HDD, втрое дешевле по цене хранения, нагрузка на запись низкая.
- Cold - ноды с более дешёвыми дисками и меньшей памятью; индексы туда переезжают через ILM
allocateс атрибутомdata: cold, снепшоты уходят в S3 через SLM (у клиента есть X-Pack лицензия).
Распределение по времени выбрали исходя из профиля запросов: оперативный поиск нужен за последние 7 дней, аналитика - за последние 30-40 дней, глубокий архив - редкие запросы, можно ждать.
Как выглядит ILM-политика
Политику создаём через Kibana или через API. Мы делаем через API, чтобы зафиксировать в git.
PUT _ilm/policy/logs_lifecycle
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "7d"
},
"set_priority": { "priority": 100 }
}
},
"warm": {
"min_age": "7d",
"actions": {
"allocate": {
"require": { "data": "warm" }
},
"forcemerge": { "max_num_segments": 1 },
"shrink": { "number_of_shards": 1 },
"set_priority": { "priority": 50 }
}
},
"cold": {
"min_age": "30d",
"actions": {
"allocate": {
"require": { "data": "cold" }
},
"freeze": {},
"set_priority": { "priority": 0 }
}
},
"delete": {
"min_age": "365d",
"actions": {
"delete": {}
}
}
}
}
}
Несколько моментов, которые стоит объяснить.
forcemerge на фазе warm - обязательно. Индекс, который больше не пишется, содержит много сегментов от инкрементальных апдейтов. После forcemerge в один сегмент он занимает меньше места и быстрее читается. На больших индексах это занимает время - планируй так, чтобы warm-фаза начиналась не в пиковую нагрузку.
shrink до одного шарда - спорный момент. Пока индекс горячий, у него пять шардов для параллельной записи. После rollover запись в него прекратилась - пять шардов это просто пять файлов без выигрыша. Shrink объединяет их в один. Минус: операция создаёт новый индекс и переносит данные, это нагрузка на кластер. На нашем объёме приемлемо.
freeze на cold - замороженный индекс открывается под запрос и тут же закрывается обратно. Это сильно снижает потребление heap: frozen-индекс не держит file descriptor-ы постоянно открытыми. Параллельно SLM (Snapshot Lifecycle Management) делает снепшоты в S3 для резервного копирования. Индексы физически остаются на cold-нодах, но потребление памяти кластера сокращается заметно.
Что получилось по месту
До ILM-реструктуризации кластер держал примерно 14 месяцев данных на дисках нод общим объёмом около 4 Тб. После того как подняли cold-tier и прогнали через политику историю старше 30 дней:
- На горячих NVMe-нодах осталось только 7 дней. Данные 7-30 дней переехали на SATA warm-ноды.
- Данные 30-365 дней переехали на дешёвые cold-ноды и заморожены. Там они сжаты forcemerge + best_compression и потребляют минимум heap.
- Итого средневзвешенная стоимость хранения упала примерно на 60% за счёт перераспределения между классами железа.
Точные цифры зависят от профиля данных - у нас логи, которые хорошо сжимаются. Если хранить бинарные документы - картина будет другой.
Подводные камни при переходе
Существующие индексы без ILM-политики. Новые индексы сразу создаются с политикой через index template. Старые - нужно назначать политику вручную или скриптом. Мы написали короткий Python-скрипт, который пробегает по индексам старше недели и назначает политику с нужной начальной фазой.
Временные рамки фаз - они от создания индекса, не от сейчас. Если назначить политику на индекс которому уже 20 дней, warm-фаза с min_age: 7d сработает немедленно. Надо быть готовым к тому что forcemerge и shrink начнут работу сразу после назначения политики. Лучше делать это в нерабочее время.
Frozen-индексы и задержки запросов. Первый запрос к замороженному cold-индексу заметно медленнее - нужно открыть шарды и прочитать с диска. Если у вас есть дашборды с диапазоном «за год» - они будут задумываться. Клиент предупреждён и понимает компромисс.
EQL: смотрим краем глаза
В 7.6 улучшили EQL (Event Query Language) - язык для последовательных запросов по событиям безопасности. Нас это касается в контексте одного клиента у которого SOC и SIEM-сценарии. EQL позволяет писать запросы типа «найди процесс A, за которым в течение 5 минут последовало событие B на том же хосте» - то, что на обычном query DSL требует вложенных агрегаций и боли.
Пока это технологическое превью, на продакшн не ставим. Но поигрались в лаборатории - синтаксис вменяемый, концепция понятная. Если к GA будет стабильно - будет о чём рассказать подробнее.
Где сейчас
ILM-политика работает первую неделю. Горячие индексы роллируются по достижении 50 Гб или 7 дней, переезжают на warm, там сжимаются и схлопываются. Cold-tier принял первую партию архивных данных без нареканий. Мониторим через Kibana Index Lifecycle Management UI - там наглядно видно в какой фазе находится каждый индекс и почему.
Оставшееся: настроить алёрты на зависшие ILM-переходы (бывает при нехватке места на warm-нодах) и проверить как ведут себя frozen-индексы при рестарте нод. Это на следующей неделе.