linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Observability и мониторинг/prometheus-basics

kb/observability ── Observability и мониторинг ── intermediate

Prometheus: scrape, TSDB, PromQL и production-pitfalls

Prometheus - сервер мониторинга: сам опрашивает приложения по HTTP, собирает числовые метрики, хранит во встроенной БД ~15 дней. По ним строят графики в Grafana и алерты через Alertmanager. Стандарт de-facto в Kubernetes.

view as markdownaka: prometheus, promql, prometheus-tsdb, prometheus-architecture

Зачем Prometheus

До Prometheus monitoring был push-based: агент на хосте слал метрики в Graphite/Nagios. Проблемы:

  • Агент знает адрес сервера, файрвол открыт обратно
  • При падении сервера agent копит локально или теряет
  • Конфигурация дублируется на каждом хосте
  • Service discovery, отдельная боль

Prometheus (2012, SoundCloud, потом CNCF) перевернул модель: сервер сам scrape (HTTP GET) target'ы. Преимущества:

  • Один центральный конфиг
  • Service discovery встроенный (k8s, Consul, EC2, file)
  • Down-detection бесплатно (up == 0)
  • Pull можно из интранета через push gateway если нужно

Сегодня Prometheus + Grafana, де-факто стандарт metrics в Kubernetes и cloud-native.

Архитектура

┌─────────────┐   scrape (HTTP /metrics)
│ Prometheus  │ ◄─────────────┬──────────┐
│   server    │               │          │
│ ┌─────────┐ │            ┌──┴──┐   ┌───┴───┐
│ │  TSDB   │ │            │ app │   │ node- │
│ │ (15d)   │ │            │ /m  │   │ exp   │
│ └─────────┘ │            └─────┘   └───────┘
│ ┌─────────┐ │
│ │ rules   │ ──► alerts ──► Alertmanager ──► PagerDuty/Slack
│ │ engine  │ │
│ └─────────┘ │
│             │
│ remote_write│ ──► VictoriaMetrics / Thanos / Mimir (long-term)
└─────────────┘
      ▲
      │ PromQL HTTP
┌─────┴────┐
│  Grafana │ + ad-hoc queries
└──────────┘

Key components:

  • scrape engine, pulls /metrics каждые 15-60s
  • TSDB, local time-series DB, blocks по 2 часа
  • rules engine, оценивает recording + alerting rules каждые 15s
  • HTTP API, /api/v1/query, /query_range, для Grafana и promtool

Pull-модель: scrape

Каждый target экспортит /metrics в text format ([[metric-types|OpenMetrics]]):

# HELP http_requests_total Number of requests
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 12345
http_requests_total{method="POST",status="500"} 12

Конфиг scrape:

yaml
scrape_configs:
  - job_name: my-app
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /metrics
    static_configs:
      - targets: ['app1:8080', 'app2:8080']

В реальности, не static, а через [[service-discovery-prometheus|service discovery]] (k8s endpoints, Consul, file_sd).

TSDB, как хранится

Time-series identifier: metric_name{label1=val1,label2=val2}. Каждая уникальная комбинация = отдельный series.

На диске:

/var/lib/prometheus/
├── 01HABC.../          # 2-часовой block
│   ├── chunks/
│   ├── index           # postings: label → series IDs
│   ├── tombstones
│   └── meta.json
├── 01HABD.../
└── wal/                # write-ahead log (current 2h window)

Compaction: 2h blocks → 16h → 5d → 14d, как LSM-tree. После retention (default 15d), удалить.

Memory ≈ 3 KB на active series + WAL. 1M series ≈ 3-4 GB RAM.

PromQL, query language

4 типа запросов:

Instant query, значение в момент времени:

up                    # все 'up' gauge сейчас
rate(http_requests_total[5m])    # rate за последние 5 мин

Range query, series за период (для графиков):

GET /api/v1/query_range?query=up&start=...&end=...&step=15s

Aggregation через sum, avg, max, min, count, topk:

sum by (job)(up)              # сколько up по job
topk(5, rate(http_requests_total[5m]))  # топ-5 по rate
histogram_quantile(0.99, sum by (le)(rate(req_duration_bucket[5m])))

Functions:

  • rate(counter[5m]), per-second rate, handles reset
  • irate(counter[1m]), instant rate, для волатильных
  • increase(counter[1h]), total за час (= rate * window)
  • delta(gauge[1h]), изменение
  • predict_linear(gauge[1h], 4*3600), прогноз через 4ч (для disk-full)

PromQL векторный: операции on labels:

rate(http_requests_total{status="500"}[5m])
  /
rate(http_requests_total[5m])
  > 0.05    # error rate >5%

Recording rules, pre-compute

Дорогие queries (особенно с histogram_quantile и multi-join) кэшируем как recording rules, Prometheus сам их вычисляет каждые 15s и пишет как обычные series:

yaml
groups:
  - name: app_slo
    interval: 30s
    rules:
      - record: app:http_request_rate:5m
        expr: sum by (job, status)(rate(http_requests_total[5m]))
      - record: app:http_request_duration:p99:5m
        expr: histogram_quantile(0.99,
                sum by (job, le)(rate(http_request_duration_bucket[5m])))

Convention: aggregation_level:metric:window. Используется в dashboards и [[alerting-rules-alertmanager|alerting]].

Alerting rules

yaml
groups:
  - name: app
    rules:
      - alert: HighErrorRate
        expr: app:http_error_rate:5m > 0.05
        for: 5m            # должно держаться 5 мин
        labels:
          severity: critical
        annotations:
          summary: "Error rate {{ $value | humanizePercentage }}"
          runbook: "https://wiki/runbooks/high-error-rate"

Если expr возвращает не-empty vector for: 5m, alert fires в Alertmanager. См. alerting-rules-alertmanager.

Retention и remote_write

Local TSDB, короткое хранение (default 15d, max ~2 месяца). Для долгосрочного, remote_write в системы заточенные под scale:

BackendStorageTenancyCompat
Thanosobject (S3/GCS)per-tenantPromQL
Cortex / Mimirobjectmulti-tenantPromQL
VictoriaMetricsown LSMYES (cluster)PromQL+MetricsQL
M3DBownmulti-tenantPromQL
InfluxDB v3ownyesInfluxQL/Flux
yaml
remote_write:
  - url: https://victoria-metrics:8480/api/v1/write
    queue_config:
      max_samples_per_send: 5000
      capacity: 50000

Production setup: Prometheus как scraper+short-term, VictoriaMetrics cluster для 1+ year retention и querying.

Federation, иерархия Prometheus

Региональный Prom скрейпит локальные сервисы. Глобальный Prom скрейпит агрегаты с региональных через /federate:

yaml
scrape_configs:
  - job_name: federate
    honor_labels: true
    metrics_path: /federate
    params:
      match[]:
        - '{__name__=~"job:.*"}'   # только recording rules
    static_configs:
      - targets: ['region-prom-eu:9090', 'region-prom-us:9090']

Не federate raw метрики, только агрегаты. Иначе cardinality умножится.

Когда что-то пошло не так

  • Prometheus OOM, обычно cardinality. topk(20, count by (__name__)({})) покажет top metrics по series count. См. cardinality-explosion.
  • up == 0 для target, scrape failed. Проверь /targets UI: timeout, DNS, 401, TLS. Логи Prom скажут точнее.
  • rate() возвращает NaN, counter сбросился между samples (рестарт), или нет samples в окне. Расширь окно или проверь scrape.
  • Расхождение между Prom и Grafana, step в range query. Маленький step = больше точек = тяжелее query.
  • WAL replay долгий после рестарта, 2-3 минуты на 1M series. Решение: --storage.tsdb.wal-segment-size=128MB или Thanos sidecar.
  • Высокий 5xx rate в /api/v1/query, длинные queries timeout. Используй recording rules или увеличь --query.timeout.
  • out of bounds ошибки в logs, clock skew между Prom и target, или target отдаёт sample из будущего. Поправь NTP (chrony-and-ntp).
  • Метрики прыгают на 0 раз в N минут, scrape duration > scrape interval, target не успевает. Уменьши metrics или увеличь interval.

Альтернативы

ИнструментКогда выбирать
Prometheusдефолт для k8s, < 10M active series
VictoriaMetrics10×lighter RAM, кластер, drop-in PromQL
Thanosхочешь S3-storage без отдельного DB-стэка
MimirGrafana Labs, multi-tenant SaaS-like
InfluxDBtagged events, tracing-like queries
Datadoghosted, не хочется OPS Prom-стэка

§ команды

bash
promtool query instant 'up == 0'

Найти все scrape targets которые сейчас down

bash
promtool tsdb analyze /var/lib/prometheus/

Анализ TSDB: топ метрик по cardinality, размеры blocks, WAL state

bash
curl -X POST localhost:9090/-/reload

Reload конфигов и rules без рестарта (требует --web.enable-lifecycle)

bash
curl -s 'localhost:9090/api/v1/query?query=count by (__name__)({}) > 1000'

Метрики с >1000 series - первые кандидаты на cardinality cleanup

bash
promtool check rules /etc/prometheus/rules/*.yml

Валидация recording + alerting rules перед reload (CI-friendly)

bash
promtool query range --start=1h --end=now --step=15s 'rate(http_requests_total[5m])'

Range query за час с шагом 15s - то же что Grafana дёргает

bash
curl -s localhost:9090/api/v1/status/tsdb | jq '.data.headStats'

Stats по in-memory head: active series, chunks, samples - быстрая cardinality-проверка

§ см. также

  • metric-typesТипы метрик: counter, gauge, histogram, summary4 типа метрик: counter (только вверх), gauge (любое значение), histogram (buckets для p99), summary (quantile в клиенте). Native histogram (Prom 2.40+) - sparse buckets, аккуратнее по памяти. Exemplars связывают метрику с trace_id.
  • service-discovery-prometheusService discovery в Prometheus: k8s, Consul, file_sd, relabelProm discoverит targets через k8s API, Consul, file_sd (static). relabel_configs - до scrape (filter+rewrite labels). metric_relabel - после scrape (drop bad metrics). Без relabel - cardinality из k8s взрывается.
  • alerting-rules-alertmanagerAlertmanager: route tree, inhibit, dedup, on-callAlertmanager - принимает alerts от Prometheus, дедупит, группирует, роутит по route tree в PagerDuty/Slack/email. Inhibit suppress'ит зависимые alerts при upstream-падении. Silence на время maintenance. Шум убивает on-call.
  • cardinality-explosionCardinality explosion: как убить Prometheus и как чинитьCardinality = uniq(metric × labels). Каждый series ≈ 3 KB RAM, 10M series = 30 GB RAM, Prom OOM-цикл. Source: user_id-labels, пути с ID, dynamic version. Diag - topk по __name__. Cure - drop labels через relabel или нормализация в коде.
  • opentelemetryOpenTelemetry: signals, OTLP, Collector pipelineOpenTelemetry - CNCF-стандарт для metrics+traces+logs в одном SDK. OTLP протокол (gRPC или HTTP). Collector принимает, фильтрует, роутит в Prom/Tempo/Loki/Jaeger. Auto-instrumentation без code change.
  • kubelet-internalskubelet - архитектура агента ноды Kuberneteskubelet - демон на каждой ноде. Получает PodSpec через API, запускает контейнеры через CRI, монтирует volumes через CSI, следит за health. При pressure делает eviction. Image GC и cgroup-tree - тоже его.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки