Как работает Prometheus и чем он отличается от других систем мониторинга?
Как работает Prometheus
Prometheus — это open-source система мониторинга для сбора и обработки метрик временных рядов. Её ключевые элементы и принципы работы:
-
Pull-модель сбора: Prometheus регулярно скрейпит (scrape) целевые эндпойнты (/metrics), которые экспонируют метрики в простом текстовом формате. Сервер сам инициирует сбор, что упрощает обнаружение недоступных целей и отказоустойчивость.
-
Экспортеры: приложения либо используют клиент-библиотеки (Go/Java/Python/…) для экспонирования метрик, либо используют готовые экспортеры (node_exporter, cadvisor, blackbox_exporter) для сервисов/инфраструктуры.
-
Модель данных: метрика — это имя + набор меток (labels). Каждая временная серия уникальна комбинацией имени и меток. Это многомерная (label-based) модель, в отличие от древовидных имён в старых системах.
-
TSDB: встроенная time-series DB в Prometheus хранит данные локально с configurable retention; оптимизирована для записи надёжных временных рядов.
-
PromQL: мощный язык запросов для агрегации, преобразования и расчёта перцентилей, скоростей (rate), и др. Позволяет строить дашборды, SLO/SLA вычисления и правила записи.
-
Alerting: правила алертов пишутся в Prometheus; при срабатывании они отправляются в Alertmanager, где выполняются группировка, дедупликация, маршрутизация, ингибиция и эскалации (PagerDuty, email, Slack).
-
Service Discovery: Prometheus интегрируется с Kubernetes, Consul, EC2 и др. для автоматического обнаружения целей.
-
Расширяемость: для HA и долгосрочного хранения интегрируется с Thanos, Cortex, Mimir, VictoriaMetrics через remote_write/remote_read и federation.
Ключевые особенности и отличия от других систем
-
Pull vs Push
Prometheus ориентирован на pull-модель; многие другие системы (Graphite/Carbon, InfluxDB, StatsD) часто используют push (агенты отправляют данные). Pull удобнее для динамичных сред (k8s) и для надёжного определения недоступных таргетов; push нужен для краткоживущих задач — в Prometheus для этого есть Pushgateway (но он предназначен только для batch jobs). -
Многомерная модель (labels)
Prometheus использует labels, что даёт гибкость в агрегации и разбивке метрик. В Graphite метрики — путь вида service.host.metric, что менее гибко. Теги у Datadog/Influx аналогичны, но PromQL даёт более мощные трансформации. -
PromQL vs простые агрегаторы
PromQL — полноценный язык для временных рядов (rate(), histogram_quantile(), increase(), irate() и т.д.), позволяет строить сложные выражения прямо в мониторинге. В ряде старых систем такой выразительности нет. -
Экосистема и облачно-нативность
Prometheus стал стандартом в Kubernetes-мире: node_exporter, kube-state-metrics, сервис-дискавери, экспортеры для почти всего. Многие SaaS-решения (Datadog, New Relic) предоставляют аналогичные функции, но как платные managed-сервисы. -
Масштабирование и долговременное хранение
Прометей из коробки — single-binary с локальным TSDB, не рассчитан на неограниченный retention и multi-tenant в крупном масштабе. Для глобального масштаба/HA используют Thanos/Cortex/VictoriaMetrics, которые добавляют долгосрочное хранение, горизонтальное масштабирование и запросы по нескольким кластерам.
Практические моменты и ограничения
-
Кардинальность меток: большое количество уникальных label-значений (user_id, session_id) приводит к взрыву временных рядов и быстрому росту памяти/диска — нужно ограничивать cardinality.
-
Типы метрик: counter, gauge, histogram, summary — правильно выбирать тип для задач (histogram + histogram_quantile для latency).
-
Recording rules: вычисления тяжёлых выражений на лету сохраняют предвычисленные серии и снижают нагрузку на дашборды.
-
Безопасность и доступ: по умолчанию Prometheus не предоставляет сложной аутентификации/многопользовательской авторизации — в production обычно ставят прокси/ingress с TLS, auth и RBAC.
-
Linking with tracing: exemplars в новых версиях позволяют помечать метрики ссылками на trace_id, упрощая RCA (связь метрик ↔ трейсы).
Примеры PromQL
-
скорость запросов: rate(http_requests_total[5m])
-
error rate: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
-
p95 latency (из buckets): histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, job))