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 и мониторинг/sli-slo-error-budget

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

SLI / SLO / error budget: SRE-метрики без шума

SLI - метрика для пользователя (availability, p99 latency). SLO - цель за период (99.9% за 30d). Error budget = 1-SLO, расходуется на инциденты+релизы. Multi-window burn rate alerting заменяет threshold-алерты, меньше шума.

view as markdownaka: slo, sli, error-budget, burn-rate, multi-window-burn-rate

Зачем SLI/SLO

Threshold-алерт «CPU > 80%», почти всегда мусор:

  • 80% CPU = OK на batch worker, problem на user-facing
  • Не отражает что чувствует пользователь
  • Шум (flap, false-positive) убивает on-call

Google SRE подход (книга «Site Reliability Engineering»):

  1. Определи SLI, Service Level Indicator. Метрика близкая к пользователю: % успешных запросов, p99 latency.
  2. Установи SLO, Service Level Objective. Цель за период: «99.9% запросов успешны за 30 дней».
  3. Вычисли error budget: 1 - SLO. У 99.9% = 0.1% разрешённого downtime = 43 минуты в месяц.
  4. Расходуй budget на: инциденты, рискованные релизы, эксперименты.
  5. Алерт срабатывает когда burn rate budget'а превышает порог.

Это сдвигает разговор от «что-то сломалось» к «сколько у нас осталось права быть сломанным».

SLI vs SLO vs SLA

ТерминЧто
SLIIndicator - сама метрика (availability rate, latency p99)
SLOObjective - целевое значение (99.9%)
SLAAgreement - контракт с пользователем (с штрафом)
Error budget1 - SLO. Допустимый %+время сбоев

SLO внутренний (engineering tool), SLA внешний (legal, refund money).

Обычно: SLA > SLO. SLO жёстче чтобы был запас. Если SLA=99.5%, делай SLO=99.9%.

Хорошие SLI

Должны:

  • Корректно отражать user experience (если SLI зелёный, юзер счастлив)
  • Aggregatable (можно посчитать % за период)
  • Стабильно измеряемы (не флапают на пустяках)

Хорошие:

  • Availability: successful_requests / total_requests (status < 500 / total)
  • Latency: p99 < 200ms (% requests faster than threshold)
  • Throughput: actual_qps / target_qps
  • Correctness: correct_results / total_results (для batch jobs)
  • Freshness: data_age_p99 < 5min (для pipelines)

Плохие:

  • CPU%: не отражает user experience
  • Avg latency: hides tail (p99 = 5s, avg = 100ms, пользователь злой, метрика «зелёная»)
  • «Пользователь жаловался»: not aggregatable

Window: rolling vs calendar

Rolling 30d: «за последние 30 дней, 99.9% success». Каждый момент считается заново. Стандарт SRE.

Calendar month: «октябрь 99.9%». Простой для бизнеса, но bad behavior на стыках месяцев.

Используй rolling.

Error budget, как считать

SLO = 99.9% за 30 дней.

Error budget = 1 - 0.999 = 0.001 = 0.1% всех запросов могут fail.

Если 100K req/day × 30d = 3M req → разрешено 3000 fail.

Прошло 15 дней, было 1500 fail = 50% budget consumed. Через 15 дней должно быть 1500 ещё. Если уже 2900, 97% consumed, остался только 100 на 15 дней.

Burn rate = consumed / time_passed. Если budget израсходован быстрее линейного, alert.

В часах:

  • 99.9% за 30d = 43.2 минуты допустимого downtime
  • 99.99% = 4.3 минуты
  • 99.999% = 26 секунд (нужны hot-standby + multi-region)

Multi-window burn rate alerting

Старый подход: алерт «error rate > 1% for 5m». Проблемы:

  • flap на коротких spike'ах
  • не различает «слегка медленно» vs «выгораем budget за час»

Multi-window burn rate (Google SRE Workbook ch. 5):

yaml
groups:
  - name: slo
    rules:
      # Burn rate за 5m и 1h одновременно
      - alert: ErrorBudgetBurnFast
        expr: |
          (
            sum(rate(http_requests_total{status=~"5.."}[5m])) /
            sum(rate(http_requests_total[5m]))
          ) > (14.4 * 0.001)
          and
          (
            sum(rate(http_requests_total{status=~"5.."}[1h])) /
            sum(rate(http_requests_total[1h]))
          ) > (14.4 * 0.001)
        for: 2m
        labels: {severity: critical}
        annotations:
          summary: "Сжигаем budget со скоростью 14.4×, за час потеряем 2% (30-day budget)"
      - alert: ErrorBudgetBurnSlow
        expr: |
          (
            sum(rate(http_requests_total{status=~"5.."}[1h])) /
            sum(rate(http_requests_total[1h]))
          ) > (3 * 0.001)
          and
          (
            sum(rate(http_requests_total{status=~"5.."}[6h])) /
            sum(rate(http_requests_total[6h]))
          ) > (3 * 0.001)
        for: 15m
        labels: {severity: warning}

Магия двух окон:

  • Короткое окно (5m), быстро реагируем
  • Длинное окно (1h), фильтруем флапы

Multipliers (14.4 для fast, 3 для slow), выведены чтобы page рано если сжигаем за день (fast) или за неделю (slow).

Burn-rate cheatsheet

Для SLO 99.9% (budget 0.1%):

Burn rateВремя до full burnКогда page
14.4×2.1 day2-min page (fast)
6×5 days15-min page (medium)
3×10 days1h page (slow)
1×30 days (planned)no page

Источник: Google SRE Workbook, table 5-2.

Error budget policy

Кодифицируй что делать когда budget кончился. Пример:

Error Budget Policy v1.4
Если за rolling 30d:
 - Budget < 0%: code freeze. Только bugfix-релизы.
   SRE и dev делят priorities 50/50 на reliability work.
 - Budget < 25%: rollout ограничен (slow rollout).
   Канареечные релизы обязательны.
 - Budget > 25%: normal velocity.
Reset budget, только пройденное время.
Не «прощаем» инциденты ретроспективно.

Без policy, SLO просто слайд в дашборде. С policy, реальный governance: dev команда видит реальную цену плохих релизов.

SLO для разных систем

SystemSLISLO
Web APIsuccess rate, p99 latency99.9% / p99 < 200ms
Async queueprocessed rate99.99% (queue HA)
Batch ETLfreshness, correctnessfreshness < 1h, correctness 100%
Cachehit rate? no, это не user-facinglatency p99 < 50ms
Searchrelevance score, latencylatency p95 < 1s, relevance > 0.7

Cache hit rate, internal metric, не SLI. SLI, что видит пользователь (latency).

Prometheus recording rules для SLO

yaml
groups:
  - name: slo_recording
    interval: 30s
    rules:
      # Per-service availability
      - record: slo:request_availability:ratio_rate5m
        expr: |
          sum by (service)(rate(http_requests_total{status!~"5.."}[5m]))
          /
          sum by (service)(rate(http_requests_total[5m]))
      # Per-service latency SLI
      - record: slo:request_latency:ratio_rate5m
        expr: |
          sum by (service)(rate(http_request_duration_seconds_bucket{le="0.2"}[5m]))
          /
          sum by (service)(rate(http_request_duration_seconds_count[5m]))

Burn-rate alerting использует эти recording rules вместо raw queries. Дешевле, читабельнее.

Tools

  • Sloth (CNCF), генерит SLO + alerting + recording rules из YAML-spec
  • OpenSLO, стандарт SLO-spec, поддерживается Sloth/Nobl9
  • Pyrra, UI для SLO-as-code в Kubernetes
  • Grafana SLO (paid), managed SLO в Grafana Cloud

Sloth example:

yaml
apiVersion: sloth.slok.dev/v1
kind: PrometheusServiceLevel
spec:
  service: api
  slos:
    - name: availability
      objective: 99.9
      sli:
        events:
          error_query: sum(rate(http_requests_total{status=~"5.."}[{{.window}}]))
          total_query: sum(rate(http_requests_total[{{.window}}]))
      alerting:
        page_alert: {labels: {severity: critical}}
        ticket_alert: {labels: {severity: warning}}

Sloth генерит recording+alerting rules автоматически с правильной multi-window burn rate.

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

  • SLO не достигнут, но budget положительный, окно 30d, флап был 30 дней назад, выпал. Норма.
  • Budget = 100% всё время, SLO слишком слабый. Поджимай.
  • Budget burn alerting не firing на real outage, burn rate multiplier слишком высокий, или SLI не отражает affected requests. Например, SLI на rate, outage на latency.
  • Cardinality explosion в SLO recording, sum by (user_id) сделал миллион series. См. cardinality-explosion.
  • Disagreement между команд про SLO, норма. Договариваться через iterations, не один раз навсегда.
  • «Если пишем p99, p999 нужен», нет. p99 покрывает 99% user-experience. p999 = noise + ML-territory.

Anti-patterns

  • SLO без budget policy, engineering theater
  • SLO 100%, невозможно, error budget = 0, любая деплоя ломает
  • SLI на internal metric (CPU, memory), не отражает user
  • Алерт на любой error, нужен for: или multi-window burn rate
  • Multiple SLOs которые перекрываются, choose one user-facing

§ команды

bash
promtool query instant 'slo:request_availability:ratio_rate5m'

Текущая availability SLI - 1.0 = всё успешно, 0.999 = 0.1% errors

bash
sloth generate -i slo.yaml -o rules.yaml

Sloth: spec → готовые recording+alerting rules для Prometheus

bash
curl -s 'http://prom:9090/api/v1/query?query=1-slo:request_availability:ratio_rate30d' | jq

Сколько budget израсходовано за 30d - алертинг material

bash
amtool alert query alertname=ErrorBudgetBurnFast

Текущие fast-burn alerts по error budget

bash
promtool check rules slo-rules.yaml

Валидация SLO recording+alerting rules - синтаксис, expr-references

bash
kubectl apply -f slo-spec.yaml -n slo  # OpenSLO via Pyrra

SLO-as-code: Pyrra оператор поднимет recording rules в Prom

§ см. также

  • alerting-rules-alertmanagerAlertmanager: route tree, inhibit, dedup, on-callAlertmanager - принимает alerts от Prometheus, дедупит, группирует, роутит по route tree в PagerDuty/Slack/email. Inhibit suppress'ит зависимые alerts при upstream-падении. Silence на время maintenance. Шум убивает on-call.
  • prometheus-basicsPrometheus: scrape, TSDB, PromQL и production-pitfallsPrometheus - сервер мониторинга: сам опрашивает приложения по HTTP, собирает числовые метрики, хранит во встроенной БД ~15 дней. По ним строят графики в Grafana и алерты через Alertmanager. Стандарт de-facto в Kubernetes.
  • metric-typesТипы метрик: counter, gauge, histogram, summary4 типа метрик: counter (только вверх), gauge (любое значение), histogram (buckets для p99), summary (quantile в клиенте). Native histogram (Prom 2.40+) - sparse buckets, аккуратнее по памяти. Exemplars связывают метрику с trace_id.
  • opentelemetryOpenTelemetry: signals, OTLP, Collector pipelineOpenTelemetry - CNCF-стандарт для metrics+traces+logs в одном SDK. OTLP протокол (gRPC или HTTP). Collector принимает, фильтрует, роутит в Prom/Tempo/Loki/Jaeger. Auto-instrumentation без code change.
  • 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 или нормализация в коде.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки