Создание и использование Recording Rules для оптимизации сложных запросов и снижения нагрузки
«Предрасчёт — это кэш для метрик»
Сложные PromQL запросы могут быть дорогими:
# Тяжёлый запрос: агрегация по всем инстансам и эндпоинтам
sum by (service, endpoint) (rate(http_requests_total[5m]))Проблемы:
Решение: Recording Rules — предрасчёт результата и сохранение как новой метрики.
Recording Rule — предварительно вычисленный запрос, результат которого сохраняется как новая метрика.
# Конфигурация правила
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))Что происходит:
service:http_requests:rate5mПреимущества:
groups:
- name: recording_rules
interval: 30s # Как часто вычислять (по умолчанию = evaluation_interval)
rules:
- record: <имя_новой_метрики>
expr: <PromQL выражение>
labels:
<дополнительные_лейблы>Конвенция: уровень:метрика:агрегация
- record: job:http_requests:rate5m
expr: sum by (job) (rate(http_requests_total[5m]))
- record: instance:node_cpu:avg_rate5m
expr: avg by (instance) (rate(node_cpu_seconds_total[5m]))
- record: service:http_latency:p95
expr: histogram_quantile(0.95, sum by (service, le) (rate(http_duration_bucket[5m])))Уровни:
job — агрегация по jobinstance — по инстансуservice — по сервисуcluster — по кластеруДо:
# Запрос в Grafana (выполняется каждый раз)
sum by (service) (rate(http_requests_total[5m]))После:
# recording_rules.yml
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))# Запрос в Grafana (готовая метрика)
service:http_requests:rate5mДо:
# Дорогой запрос: histogram_quantile + aggregation
histogram_quantile(0.95,
sum by (service, le) (rate(http_request_duration_seconds_bucket[5m]))
)После:
- record: service:http_latency:p95
expr: histogram_quantile(0.95,
sum by (service, le) (rate(http_request_duration_seconds_bucket[5m]))
)
- record: service:http_latency:p99
expr: histogram_quantile(0.99,
sum by (service, le) (rate(http_request_duration_seconds_bucket[5m]))
)# Быстрый запрос
service:http_latency:p95- record: service:http_errors:rate5m
expr: sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))
- record: service:http_error_rate:ratio5m
expr: service:http_errors:rate5m / service:http_requests:rate5mИспользование:
# Процент ошибок по сервисам
service:http_error_rate:ratio5m * 100- record: cluster:node_cpu:avg_usage
expr: |
100 - avg by (cluster) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100- record: service:availability:ratio5m
expr: |
avg by (service) (up{job=~"api|worker"})
* 100До:
- alert: HighErrorRate
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
/
sum by (service) (rate(http_requests_total[5m]))
> 0.05После:
# Recording rules
- record: service:http_errors:rate5m
expr: sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))
- record: service:http_error_rate:ratio5m
expr: service:http_errors:rate5m / service:http_requests:rate5m
# Алерт
- alert: HighErrorRate
expr: service:http_error_rate:ratio5m > 0.05Преимущества:
Создавайте многоуровневые правила:
groups:
# Уровень 1: базовые агрегации
- name: base_aggregations
rules:
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))
- record: service:http_errors:rate5m
expr: sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
# Уровень 2: производные метрики
- name: derived_metrics
rules:
- record: service:http_error_rate:ratio5m
expr: service:http_errors:rate5m / service:http_requests:rate5m
- record: service:http_requests:day_over_day
expr: |
service:http_requests:rate5m
/
service:http_requests:rate5m offset 1d# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 30s # Как часто вычислять правила
rule_files:
- "recording_rules/*.yml"
- "alerting_rules/*.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']# Проверка синтаксиса
promtool check rules recording_rules.yml
# Загрузка в Prometheus (без перезапуска)
curl -X POST http://localhost:9090/-/reloadВ Prometheus UI:
# ПЛОХО
- record: http_aggregated
expr: sum(rate(http_requests_total[5m]))
# ХОРОШО
- record: job:http_requests:rate5m
expr: sum by (job) (rate(http_requests_total[5m]))Не создавайте правила для метрик, которые уже есть:
# ПЛОХО: дублирует существующую метрику
- record: http_requests_total
expr: http_requests_total# recording_rules/http.yml
- record: service:http_requests:rate5m
- record: service:http_latency:p95
# recording_rules/node.yml
- record: instance:node_cpu:avg
- record: instance:node_memory:usage- record: service:http_error_rate:ratio5m
expr: service:http_errors:rate5m / service:http_requests:rate5m
labels:
description: "Error rate ratio by service"
owner: "platform-team"# Время вычисления правил
prometheus_rule_evaluation_duration_seconds
# Ошибки вычисления
prometheus_rule_evaluation_failures_total
# Последнее вычисление
prometheus_rule_last_evaluation_timestamp_secondsСоздавайте правила только для:
Не нужно для:
Причины:
Решение:
# Проверка синтаксиса
promtool check rules recording_rules.yml
# Проверка в Prometheus UI
Status → Rules → ищите ошибкиПричины:
Решение:
# Уменьшите интервал для группы
- name: recording_rules
interval: 15s # Вместо 30s
rules:
- record: ...Recording Rules создают новые метрики — не злоупотребляйте.
Решение:
уровень:метрика:агрегация (job:http_requests:rate5m).В следующей теме вы изучите многоуровневый алертинг — построение иерархии warning/critical, эскалацию и dependency-aware алерты.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.