Глубокое погружение в PromQL: подзапросы, корреляции, прогнозирование, оптимизация производительности запросов
«PromQL — это не просто запросы, это язык мышления о метриках»
Вы уже знаете основы PromQL: rate(), агрегации, histogram_quantile(). Теперь углубимся в сложные паттерны, оптимизацию и edge cases.
Подзапросы позволяют применять функции к результату другого запроса.
function[resolution:step]resolution — диапазон данныхstep — интервал между точками (по умолчанию = scrape_interval)# Среднее CPU за 5 минут, затем максимум за час
max_over_time(avg_over_time(node_cpu_usage_percent[5m])[1h:5m])Как работает:
avg_over_time(...[5m]) — среднее за 5 минут для каждой точки[1h:5m] — берёт эти средние за последний час (12 точек)max_over_time(...) — максимум среди этих 12 точекЗачем: сглаживает кратковременные скачки, показывает устойчивые пики.
# Как менялась скорость запросов (rate от rate)
rate(rate(http_requests_total[5m])[1h:5m])Зачем: ускорение или замедление трафика (второе производство).
# Максимальный rate за последние 24 часа
max_over_time(rate(http_requests_total[5m])[24h:5m])# Запросов сейчас vs неделю назад
sum(rate(http_requests_total[5m]))
/
sum(rate(http_requests_total[5m] offset 7d))Результат: 1.15 = на 15% больше, чем неделю назад.
# Насколько текущий rate отличается от среднего за неделю
(
sum(rate(http_requests_total[5m]))
-
avg_over_time(sum(rate(http_requests_total[5m]))[7d:1h])
)
/
avg_over_time(sum(rate(http_requests_total[5m]))[7d:1h])
* 100Результат: +25% = на 25% выше среднего за неделю.
# Корреляция между ошибками API и задержками БД
correlate(
sum(rate(api_errors_total[5m])),
avg(database_latency_seconds)
)Примечание: correlate() — экспериментальная функция, доступна не во всех версиях. Альтернатива — визуальное сравнение в Grafana.
# Предсказание места на диске через 4 часа
predict_linear(node_disk_free_bytes[24h], 4*3600)Ограничения: работает только для линейных трендов. Не подходит для циклических паттернов (дневных, недельных).
# Аномалия: текущее значение > 3 стандартных отклонений от среднего
(
node_cpu_usage_percent
-
avg_over_time(node_cpu_usage_percent[24h])
)
/
stddev_over_time(node_cpu_usage_percent[24h])
> 3Как работает: Z-score > 3 означает, что значение выходит за пределы 99.7% нормальных значений.
# Экспериментальная функция для прогнозирования временных рядов
holt_winters(node_disk_free_bytes[7d], 0.5, 0.5)Параметры: smoothing factor (0-1), trend factor (0-1).
sum by (service, endpoint, method) (rate(http_requests_total[5m]))# Группировка по всем лейблам кроме instance
sum without (instance) (rate(http_requests_total[5m]))# Сумма только для значений > 0
sum(http_requests_total > 0)# Среднее по инстансам от суммы по эндпоинтам
avg by (service) (
sum by (service, instance) (rate(http_requests_total[5m]))
)# 95-й перцентиль по всем инстансам
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
)Важно: by (le) обязателен — le (last edge) это специальный лейбл histogram.
# Среднее время ответа
sum(rate(http_request_duration_seconds_sum[5m]))
/
sum(rate(http_request_duration_seconds_count[5m]))# Какой процент запросов медленнее 1 секунды
(
sum(rate(http_request_duration_seconds_bucket{le="+Inf"}[5m]))
-
sum(rate(http_request_duration_seconds_bucket{le="1.0"}[5m]))
)
/
sum(rate(http_request_duration_seconds_count[5m]))
* 100Дорого:
# Сканирует все метрики
{__name__=~".*"}Дёшево:
# Конкретная метрика
http_requests_totalМедленно:
# Сначала берёт все метрики, потом фильтрует
{job="api"} |= "error"Быстро:
# Сразу фильтрует по лейблу
{job="api", level="error"}Медленно:
http_requests_total{endpoint=~"/api/.*"}Быстро:
http_requests_total{endpoint=~"/api/"}Плохо:
rate(http_requests_total[24h]) # Огромное окноХорошо:
rate(http_requests_total[5m]) # Разумное окноСложный запрос:
max_over_time(avg_over_time(node_cpu[5m])[1h:5m])Разбейте:
avg_over_time(node_cpu[5m])avg_over_time(...)[1h:5m]max_over_time(...)Показывает график результата — помогает понять, что происходит.
curl -g 'http://localhost:9090/api/v1/query?query=...'Apdex (Application Performance Index) — индекс удовлетворённости пользователей.
# Satisfied (<250ms) + Tolerating (250-1000ms) / 2
(
sum(rate(http_request_duration_seconds_bucket{le="0.25"}[5m]))
+
sum(rate(http_request_duration_seconds_bucket{le="1.0"}[5m]))
-
sum(rate(http_request_duration_seconds_bucket{le="0.25"}[5m]))
/ 2
)
/
sum(rate(http_request_duration_seconds_count[5m]))Результат: 0-1, где 1 = все пользователи довольны.
# Насколько быстро «сжигаем» error budget (для SLO 99.9%)
(
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
)
/ 0.001 # 0.1% допустимых ошибокИнтерпретация:
# Процент времени доступности за 30 дней
avg_over_time(up[30d]) * 100# Здоровье зависимостей (БД, кэш, внешние API)
(
avg(probe_success{job="blackbox"})
+
(1 - avg(rate(database_errors_total[5m])))
+
(1 - avg(rate(cache_errors_total[5m])))
)
/ 3 * 100[resolution:step] синтаксис.offset.predict_linear() для линейных трендов.by (le) для перцентилей, _sum / _count для среднего.В следующей теме вы изучите Recording Rules — предрасчёт сложных метрик для снижения нагрузки на Prometheus.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.