Как выбрать интервалы опроса метрик и не перегрузить систему мониторинга
Чем чаще система мониторинга собирает метрики, тем быстрее вы увидите проблему. Но за частоту платят реальными ресурсами: нагрузкой на экспортёры, сетевым трафиком и местом в хранилище. Редкий сбор дешевле, зато кратковременные инциденты пролетают между двумя опросами незамеченными.
Поэтому интервал опроса — это всегда компромисс, и решается он не одним значением в global, а по группам метрик. Разберём, из чего складывается стоимость интервала, какие границы задаёт сам Prometheus и как менять частоту осознанно.
Почему нельзя опрашивать всё каждую секунду
Каждый цикл опроса — это запрос к экспортёру, его работа по сбору данных, трафик и запись в хранилище. Пока метрик десятки, это незаметно. Проблема в том, что стоимость растёт по произведению: количество серий × частота.
Уменьшение интервала с 60 до 5 секунд не «немного увеличивает» объём данных, а увеличивает его в двенадцать раз — при том же количестве серий. Узким местом при этом становится сама система мониторинга, и обычно это выясняется в худший момент: во время инцидента, когда Prometheus не отвечает на запросы, потому что занят приёмом данных.
Посмотреть, сколько сэмплов в секунду принимает ваш Prometheus прямо сейчас, можно у него же:
rate(prometheus_tsdb_head_samples_appended_total[5m])
prometheus_tsdb_head_series
Первое — темп приёма, второе — количество активных серий. Эти два числа и есть то, чем вы управляете, выбирая интервалы.
Считаем стоимость интервала в байтах
Место в хранилище считается по простой формуле из документации Prometheus:
объём = время хранения × сэмплов в секунду × байт на сэмплПосле сжатия один сэмпл в TSDB занимает примерно 1–2 байта. Возьмём 10 000 серий:
| Интервал | Сэмплов в секунду | В сутки | За 30 дней хранения |
|---|---|---|---|
| 15 с | ~667 | ~115 МБ | ~3,4 ГБ |
| 30 с | ~333 | ~58 МБ | ~1,7 ГБ |
| 60 с | ~167 | ~29 МБ | ~0,9 ГБ |
Числа сами по себе небольшие — важна пропорция. Учетверив частоту, вы учетверяете и диск, и объём работы при каждом запросе за длинный период: график за месяц на 15-секундной сетке — это в четыре раза больше точек, которые нужно прочитать и сжать в пиксели.
Ограничения хранения задаются флагами, и лучше выставить оба:
prometheus \
--storage.tsdb.retention.time=30d \
--storage.tsdb.retention.size=50GBretention.size — страховка: он не даст диску закончиться, если количество серий внезапно вырастет после неудачного релиза с высокой кардинальностью.
Разным метрикам — разные интервалы
Самая частая ошибка — один интервал в global на все джобы. Между тем частоту можно задать для каждого джоба отдельно, и именно так и стоит делать:
global:
scrape_interval: 60s
evaluation_interval: 60s
scrape_configs:
# Время ответа, RPS и ошибки — по ним строятся алерты, нужна реакция
- job_name: 'api'
scrape_interval: 15s
scrape_timeout: 10s
static_configs:
- targets: ['api-1:9090', 'api-2:9090']
# Базовые метрики хоста: всплески видны и на 30-секундной сетке
- job_name: 'node'
scrape_interval: 30s
static_configs:
- targets: ['node-1:9100', 'node-2:9100']
# Тяжёлый экспортер: каждый скрейп — это реальные запросы к базе
- job_name: 'postgres'
scrape_interval: 120s
scrape_timeout: 60s
static_configs:
- targets: ['pg-exporter:9187']
# Сертификаты живут месяцами, но выше 5 минут поднимать нельзя — почему, ниже
- job_name: 'blackbox-ssl'
scrape_interval: 300s
scrape_timeout: 30s
static_configs:
- targets: ['blackbox:9115']Ориентиры, от которых удобно отталкиваться:
| Что измеряем | Интервал | Почему так |
|---|---|---|
| Время ответа, RPS, ошибки HTTP | 10–30 с | основа алертов, нужна быстрая реакция |
| CPU, память, сеть хоста | 30–60 с | всплески заметны и на минутной сетке |
| Heap, GC, event loop lag | 15–30 с | деградация развивается за секунды |
| Тяжёлые экспортеры БД | 60–120 с | каждый скрейп нагружает саму базу |
| Место на диске, inode | 60–300 с | заполняется часами и днями |
| Срок сертификатов, домены | 300 с | меняется раз в месяцы |
Проверить себя помогает один вопрос: что я сделаю, если увижу изменение этой метрики через 5 секунд, а не через минуту? Если ответ «ничего, я всё равно смотрю на неё в отчёте раз в неделю» — частый опрос здесь не нужен.
Границы, которые задаёт сам Prometheus
Три ограничения, о которые чаще всего спотыкаются при настройке интервалов.
Интервал больше 5 минут ломает графики. В PromQL значение считается актуальным ограниченное время — по умолчанию 5 минут (--query.lookback-delta). Если опрашивать реже, между точками появятся разрывы: график рвётся, а выражения вроде up == 0 начинают вести себя непредсказуемо. Практический вывод: 5 минут — верхняя граница разумного интервала, даже для метрик, которые меняются раз в месяц.
Окно в rate() должно быть минимум вчетверо больше интервала. Чтобы посчитать скорость, нужно хотя бы две точки в окне, а с запасом на пропущенный скрейп — четыре. При scrape_interval: 60s выражение rate(http_requests_total[1m]) будет то работать, то давать пустоту:
# плохо: окно равно интервалу опроса
rate(http_requests_total[1m])
# хорошо: окно с запасом на пропущенные скрейпы
rate(http_requests_total[5m])
Отсюда важное следствие: меняя интервал опроса, нужно пересматривать и окна во всех запросах и алертах. Увеличили интервал с 15 до 60 секунд — часть дашбордов молча опустеет.
scrape_timeout не может быть больше scrape_interval. Prometheus не запустится с такой конфигурацией. И если у джоба таймаут почти равен интервалу, следующий опрос начнётся сразу после предыдущего — экспортёр окажется под непрерывной нагрузкой.
Не забывайте про нагрузку на экспортёры
Большинство экспортёров дешёвые, но некоторые при каждом запросе делают реальную работу: обходят таблицы в базе, опрашивают JVM, собирают статистику по контейнерам или ходят по SNMP до сетевого железа. Для них частый опрос — это нагрузка на прод, а не на мониторинг.
Кто именно отвечает медленно, видно из служебных метрик:
topk(10, scrape_duration_seconds)
topk(10, scrape_samples_scraped)
Правило простое: если scrape_duration_seconds у джоба стабильно превышает половину его scrape_interval, интервал для этого экспортёра уже слишком мал. Дальше начинаются таймауты, а таймаут выглядит в мониторинге как up == 0 — то есть как ложная авария. Подробнее про сами экспортёры и их метрики — в статье о том, как расширять метрики Prometheus.
Интервал напрямую задаёт скорость обнаружения
Систему нельзя заставить узнать о проблеме быстрее, чем она получает данные. Полное время до уведомления складывается из четырёх слагаемых:
scrape_interval + for + evaluation_interval + group_waitПосчитаем на конкретных значениях: опрос раз в 30 секунд, условие for: 90s (три проверки подряд), правила вычисляются раз в 30 секунд, group_wait в Alertmanager стоит по умолчанию 30 секунд. В худшем случае получается три минуты — а не полторы, как кажется по одному лишь for.
Именно поэтому «уменьшить интервал» редко бывает правильным первым шагом. Если нужно ускорить реакцию, сначала посмотрите на остальные три слагаемых: часто там лежат минуты, которые дешевле сократить. И наоборот — если алерты шумят, увеличенный for обойдётся дешевле, чем более частый опрос. Подробнее об этом — в статьях про алерты, которые не раздражают и burn rate alerts.
Что делать вместо уменьшения интервала
Когда мониторингу становится тяжело, интервал — не первое, что стоит трогать. Обычно дешевле сократить количество серий, а не частоту:
Выбросить ненужные метрики на приёме. Экспортёры отдают куда больше, чем вам нужно. Лишнее отсекается на этапе сбора:
metric_relabel_configs:
# Гистограммы по каждому пути дают тысячи серий на один сервис
- source_labels: [__name__]
regex: 'go_gc_duration_seconds.*'
action: dropПосчитать заранее то, что считается в каждом запросе. Recording rules превращают тяжёлое выражение в одну готовую серию, и дашборд перестаёт пересчитывать его на каждое обновление:
groups:
- name: api
interval: 30s
rules:
- record: job:http_request_errors:rate5m
expr: sum by (job) (rate(http_requests_total{code=~"5.."}[5m]))Найти, кто именно съедает кардинальность. Чаще всего это одна-две метрики с идентификатором в лейбле — user id, путь с параметрами, trace id:
topk(10, count by (__name__) ({__name__=~".+"}))
Запрос тяжёлый, на большой базе его лучше выполнять не в разгар инцидента. Зато результат обычно объясняет рост хранилища лучше любых расчётов.
Пересматривайте настройки по мере роста
Интервалы, подобранные для десяти серверов, на сотне могут оказаться неподъёмными: количество серий растёт вместе с инфраструктурой, а стоимость — по произведению. Раз в несколько месяцев полезно свериться:
- сколько сэмплов в секунду принимает Prometheus и как это изменилось;
- какие джобы дают больше всего серий;
- какие метрики никем не используются — ни в дашбордах, ни в алертах;
- соответствует ли время хранения тому, как далеко в прошлое вы реально смотрите.
Оптимизация почти никогда не заключается в покупке более мощного сервера под мониторинг. Обычно это выбрасывание метрик, которые никто ни разу не открыл. Как собрать базовый стек и что в нём смотреть в первую очередь, разбирали в статье про мониторинг серверов на Prometheus и Grafana.
Что почитать дальше
- Как выбрать интервал проверки сайта для мониторинга
- Что такое monitoring exporters и как расширить метрики Prometheus
- Четыре золотых сигнала в мониторинге: latency, traffic, errors, saturation
- Что такое false positive в мониторинге и как его уменьшить
Заключение
Универсального интервала опроса не существует, но есть рабочая последовательность действий. Задайте в global спокойные 60 секунд, ускорьте отдельными джобами только то, по чему строятся алерты, замедлите тяжёлые экспортеры и не поднимайте интервал выше 5 минут даже для самых статичных метрик.
Дальше держите в голове три числа: сколько сэмплов в секунду вы принимаете, сколько это занимает на диске за срок хранения и через сколько секунд после сбоя приходит уведомление. Если хочется ускорить реакцию — сначала посмотрите на for, evaluation_interval и group_wait, а если мониторингу тяжело — на количество серий. Интервал стоит менять последним: он влияет не только на нагрузку, но и на все окна в запросах и алертах, которые придётся пересматривать вместе с ним.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний