MAATRIX / Блог / Предел глубины истории в мониторинге: сколько дней хранить, чтобы не купить диск

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

MAATRIX

Диск под мониторинг заполняется тихо: никто не замечает, как retention с 15 дней вырос до 90 «на всякий случай», а число временных рядов утроилось после добавления пары новых сервисов с богатыми лейблами. А потом Prometheus падает с out-of-disk, или счёт за хранилище метрик неожиданно догоняет счёт за сами серверы, которые он мониторит. История метрик — не бесплатный побочный продукт мониторинга, а ресурс, у которого есть цена за каждый день хранения, и эту цену стоит считать заранее, а не по факту переполненного тома.

Из чего складывается объём хранения метрик

Место, которое занимает база временных рядов, — не просто «количество метрик умножить на время». Формула чуть сложнее, но полностью в руках у того, кто настраивает мониторинг.

Базовый расчёт для систем на TSDB-движке (Prometheus, VictoriaMetrics, Thanos) выглядит так:

объём ≈ число активных временных рядов × байт на одну точку × точек в сутки × дней retention

Число активных временных рядов — это не число метрик, а число уникальных комбинаций «метрика + набор значений лейблов». Метрика http_requests_total с лейблами method, status, instance и десятью подами превращается в десятки и сотни отдельных рядов. Именно рост числа рядов, а не рост числа «метрик» в узком смысле, чаще всего и взрывает объём хранилища — это называют cardinality explosion, и на него стоит смотреть отдельно, до всякого разговора про retention.

Байт на точку зависит от движка и от того, насколько предсказуемо меняются значения. Современные TSDB (Prometheus TSDB, VictoriaMetrics, InfluxDB TSM) используют дельта-кодирование и сжатие: почти константные метрики (загрузка CPU в спокойные периоды) сжимаются намного плотнее, чем шумные (латентность под нагрузкой). Точной универсальной цифры байт/точку нет — она варьируется в разы в зависимости от природы данных и версии движка, поэтому ориентируйтесь не на абстрактное число из чужой статьи, а на фактический размер каталога данных вашей же системы за уже прошедшую неделю: он и есть самая честная оценка для экстраполяции.

Точки в сутки определяются интервалом сбора (scrape_interval в Prometheus). Уменьшение интервала с 30 до 15 секунд не удваивает нагрузку на CPU и сеть — но ровно удваивает объём хранения при прочих равных, потому что удваивает число точек на каждый ряд.

Практический способ прикинуть объём без сложной формулы: включить мониторинг, подождать сутки-двое стабильной нагрузки, посмотреть реальный прирост каталога данных за этот период (du -sh на директории данных), и экстраполировать линейно на нужный retention с запасом 30-50% на рост числа сервисов и рядов. Линейная экстраполяция работает достаточно хорошо именно потому, что объём почти пропорционален и числу рядов, и времени — оба множителя в формуле выше растут предсказуемо, если не меняется топология системы.

Зачем вообще нужна долгая история

Прежде чем резать retention до минимума, стоит честно сформулировать, для чего долгая история действительно нужна — иначе легко выбросить то, что через полгода понадобится и будет утеряно навсегда.

  • Year-over-year сравнение. Нагрузка на интернет-магазин в декабре этого года логично сравнивать с декабрём прошлого, а не с ноябрём этого же года. Без годовой истории такое сравнение просто невозможно.
  • Поиск сезонных паттернов. Недельная, месячная, квартальная цикличность нагрузки видна только на достаточно длинном ряде — на неделе данных сезонность от шума не отличить.
  • Планирование мощностей. Тренд роста потребления ресурсов за 6-12 месяцев — основа для решения «когда апгрейдить сервер», и об этом подробнее в статье про планирование мощностей по метрикам.
  • Постфактум-расследование инцидентов. Через месяц после аварии кто-то спрашивает «а такое уже бывало?» — и ответить можно только если данные ещё живы.
  • Compliance и отчётность. В некоторых организациях есть формальное требование хранить метрики доступности определённый срок для отчётов перед заказчиками или регулятором.

При этом не вся история одинаково ценна. Секундная гранулярность полугодовой давности почти никогда не нужна в исходном виде — для year-over-year сравнения и поиска сезонности достаточно намного более грубого разрешения. Это наблюдение и лежит в основе downsampling — держать детальные данные недолго, а огрублённые сводки долго и почти бесплатно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Downsampling: как срезать объём, не теряя главное

Downsampling — это агрегация старых данных до более редких точек с потерей части детализации. Вместо того чтобы хранить точку каждые 15 секунд год подряд, свежие данные держат в исходном разрешении, а данные старше определённого возраста прореживают: например, оставляют одну агрегированную точку за 5 минут вместо 20 исходных.

Ключевая идея — сохранять не просто последнюю точку интервала, а набор агрегатов: минимум, максимум, среднее и (для counter-метрик) сумму приращений. Если хранить только среднее, короткие всплески латентности или редкие ошибки бесследно растворяются в сглаженной кривой, а именно они чаще всего и интересны при расследовании. Практика:

  • Prometheus сам по себе downsampling не делает — его TSDB хранит всё с одним разрешением до истечения --storage.tsdb.retention.time. Downsampling здесь реализуют через recording rules: правило считает агрегат (например, avg_over_time за 5 минут) и пишет результат как новую метрику с более редким шагом, а исходную метрику держат в отдельном, коротком retention.
  • VictoriaMetrics поддерживает downsampling нативно в кластерной версии через флаг -downsampling.period, задавая разные интервалы хранения для разных возрастов данных одной командной строкой — заметно проще, чем городить recording rules вручную. Если тема интересна отдельно, есть статья про VictoriaMetrics вместо Prometheus.
  • Thanos реализует downsampling как отдельный компонент (Compactor), который периодически проходит по данным в объектном хранилище и создаёт агрегированные блоки с разрешением 5 минут и 1 час, оставляя исходные блоки для недавнего окна.
  • InfluxDB решает задачу через continuous queries (в 1.x) или tasks (во 2.x): фоновая задача читает данные из «сырого» bucket, агрегирует и пишет в другой bucket с более коротким интервалом опроса, но более длинным retention.

Типичная трёхуровневая схема разрешения выглядит так:

Возраст данныхРазрешениеЧто хранит
0-15 дней15-30 сек (как собрано)полная детализация для расследования инцидентов
15 дней - 3 месяца5 минутдостаточно для анализа трендов недели/месяца
3 месяца - 1-2 года1 часдостаточно для сезонности и year-over-year

Экономия от такой схемы кратная: час вместо 15 секунд — это сокращение числа точек примерно в 240 раз для данных старше трёх месяцев, и именно этот множитель делает годовую историю в принципе доступной по объёму.

Tiered storage: горячее и холодное хранение

Downsampling снижает число точек, tiered storage снижает стоимость хранения тех точек, что остались, — за счёт переноса старых, редко читаемых данных на более дешёвый носитель.

Логика та же, что и в бэкапах: свежие, часто читаемые данные должны отвечать быстро и лежат на NVMe/SSD, а старые, к которым обращаются раз в квартал ради годового сравнения, не обязаны быть такими же быстрыми и могут лежать на HDD или в объектном хранилище.

  • Thanos и VictoriaMetrics (кластерная версия) — сами архитектурно построены вокруг разделения на «горячий» локальный слой (недавние блоки) и «холодный» объектный слой (S3-совместимое хранилище) для старых блоков. Запрос по свежим данным идёт к локальному диску, запрос вглубь истории — к объектному хранилищу, обычно медленнее, но кратно дешевле за гигабайт.
  • Ручной вариант без специализированных инструментов — держать директорию данных Prometheus/InfluxDB на быстром диске с коротким retention, а по расписанию (cron + rsync или restic/borg) архивировать снапшоты данных постарше на объектное хранилище или на отдельный сервер с дешёвыми HDD. Восстановление такого архива для расследования — на отдельном временном инстансе, а не постоянная часть продакшн-стека.
  • Разные диски под разные тиры на одной машине — если нет объектного хранилища, разумный компромисс: смонтировать директорию wal и «горячий» блок на NVMe, а директорию с уже скомпакченными старыми блоками — на отдельный SATA SSD или даже HDD-том, если движок поддерживает разделение путей (у VictoriaMetrics и Thanos это штатная конфигурация).

Экономика тут прямая: холодный слой на объектном хранилище или HDD обычно в несколько раз дешевле за гигабайт, чем NVMe под базой данных, — конкретное соотношение цен зависит от провайдера и типа диска, поэтому сверяйтесь с актуальным прайсом, а не с ориентировочными цифрами из статей. При годовой истории и работе на десятках-сотнях гигабайт разница уже ощутима в бюджете; там, где счёт за мониторинг догоняет счёт за инфраструктуру, чаще всего виноват именно горячий слой, раздутый под холодные данные — это разбирается подробнее в статье цена мониторинга: сервис или своё.

Как посчитать нужный retention: пошагово

Вместо того чтобы гадать между «7 дней хватит» и «храним всё вечно», посчитайте так:

  1. Определите реальные сценарии использования истории. Инциденты расследуют за последние 2-4 недели почти всегда, year-over-year смотрят раз в квартал, capacity planning — раз в месяц-полгода. Под каждый сценарий — свой retention и своё разрешение, не один общий срок на всё.
  2. Измерьте текущий фактический прирост. du -sh на директории данных за известный период плюс число активных рядов (prometheus_tsdb_symbol_table_size_bytes и метрика prometheus_tsdb_head_series в самом Prometheus, либо аналогичные метрики движка) дают базовую скорость роста в байтах в сутки.
  3. Экстраполируйте с запасом. Умножьте суточный прирост на желаемый retention, добавьте 30-50% на рост числа сервисов и рядов за этот период — команды почти никогда не сокращаются в размере со временем.
  4. Заложите downsampling для второго и третьего тира, если нужна история дольше 2-3 месяцев — без него объём для года-двух почти всегда получается неподъёмным при разумном бюджете.
  5. Сверьте с реальным местом на диске и оставьте резерв минимум 20% свободного пространства — TSDB многих движков (в том числе Prometheus) деградирует по производительности и может начать отказывать в записи при почти полном диске, а не только при абсолютно полном.
  6. Проверьте не только объём, но и память. Активные («head») ряды в Prometheus держатся в памяти процесса, и рост cardinality бьёт по RAM раньше, чем по диску — если сервис после увеличения числа рядов начинает падать по OOM, дело в разрешении и retention головного блока, а не в глубине истории на диске.

Пример прикидки: 50 000 активных рядов, интервал сбора 15 секунд (5760 точек в сутки на ряд), retention 30 дней в полном разрешении. Даже при скромной оценке в единицы байт на сжатую точку это уже порядок десятков гигабайт только на горячий тир — и это без учёта роста числа рядов, WAL и индексов. Точную цифру для своей системы получите только измерением, но порядок величины такая прикидка даёт честно.

Типичные retention policy на практике

Готовых универсальных цифр нет — конкретный срок зависит от профиля нагрузки, бюджета и требований к отчётности, но есть ориентировочные диапазоны, от которых можно оттолкнуться:

  • Небольшой проект, один-два сервера, команда до 5 человек. Полное разрешение 15-30 дней, без второго тира — история дальше почти никогда не запрашивается, а объём и так небольшой. Настройка «из коробки» для такого случая разобрана в статье как установить и настроить Grafana и Prometheus на VPS.
  • Средний продакшн, десятки сервисов. Полное разрешение 15 дней, 5-минутный агрегат 3 месяца, часовой агрегат 6-12 месяцев — компромисс между расследованием инцидентов и capacity planning.
  • Крупная инфраструктура с формальной отчётностью или SLA. Полное разрешение 30 дней, многоуровневый downsampling, холодный тир на объектном хранилище на 1-3 года — здесь обычно уже используют Thanos или VictoriaMetrics в кластерном режиме именно ради встроенного tiered storage.
  • Мониторинг с высокой cardinality (метрики на уровне отдельных пользователей, запросов, трейсов). Здесь разумнее не растягивать retention метрик, а раньше переключаться на трейсинг и логи для детального разбора, оставляя метрикам роль агрегированной картины — разница между этими типами данных разобрана в статье логи, метрики и трассы: чем отличаются.

Резкое увеличение retention «про запас» без расчёта — частая ошибка: кто-то меняет --storage.tsdb.retention.time с 15d на 365d одной командой, не проверив ни объём диска, ни рост cardinality, и через несколько недель мониторинг падает не от нагрузки на сервисы, а от переполненного тома под собственные данные.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли просто хранить всё в полном разрешении и не думать про downsampling?

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

Downsampling теряет данные безвозвратно?

Да, если не хранить исходные блоки отдельно. Именно поэтому многотирные схемы не удаляют старые данные сразу при агрегации, а держат исходный тир ещё какое-то время, прежде чем окончательно его ротировать.

Что произойдёт, если диск под метрики заполнится полностью?

Зависит от движка, но в большинстве случаев — деградация или полная остановка записи новых точек, вплоть до падения процесса. Это не тот отказ, который стоит проверять на проде: тестируйте поведение при почти полном диске на отдельном стенде и держите алерт на свободное место с запасом.

Как понять, что retention пора сокращать, а не диск расширять?

Посмотрите статистику реальных обращений к истории старше месяца-двух (логи запросов к Grafana/API). Если такие запросы единичны, а место стабильно кончается — выгоднее сократить полное разрешение и усилить downsampling, чем постоянно наращивать диск под данные, которые почти никто не смотрит.

Нужен ли tiered storage совсем маленькому проекту?

Обычно нет — накладные расходы на настройку объектного хранилища и синхронизацию тиров для пары серверов с retention в месяц не окупаются. Многоуровневое хранение начинает иметь смысл, когда история измеряется кварталами и годами, а не неделями.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →