awesome-everything EN
↑ Обратно к восхождению

Наблюдаемость

Выбор SLI и SLO-целей: отношения, не ощущения

Суть Хороший SLI — отношение в [0%, 100%], коррелирующее с болью пользователя, а не загрузка CPU или длина очереди. Правильная SLO-цель — минимальное число, которое терпят пользователи, потому что каждая лишняя девятка умножает инженерные затраты в 3–10 раз.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Команда алертует на загрузку CPU как на основной сигнал надёжности. При автоскейлинге под нормальный трафик CPU взлетает — и пейджер срабатывает. Ни один пользователь не пострадал. SLI был неправильным.

Что делает SLI хорошим

Google SRE Workbook категоричен: хороший SLI — это отношение good events к total events в [0%, 100%], коррелирующее с тем, что чувствует пользователь. Из этого определения следуют четыре свойства.

Это должно быть отношение, а не счётчик. «Менее 100 ошибок в день» смешивает объём трафика с надёжностью. При 1,000 req/день это 10% ошибок; при 1,000,000 req/день — 0.01%. Форма отношения делает SLO сопоставимыми при любом объёме и делает error budget напрямую вычисляемым: budget = (1 − SLO) × total_events.

Должно попадать в [0%, 100%]. Это делает дашборды читаемыми (фиксированная ось) и burn rate вычислимым.

Должно отслеживать боль пользователя, а не боль машины. Запрещённый антипаттерн — «внутренний SLI»: загрузка CPU, длина очереди, паузы GC, утилизация heap. Сервер при 100% CPU может прекрасно обслуживать каждый запрос. SLI на CPU будет пейджить при здоровом autoscaling-событии, когда пользователи довольны.

Категории сигналов по типу сервиса:

Тип сервисаAvailability SLILatency SLI
Request-driven APIsuccessful_requests / total_requestsrequests_under_200ms / total_requests
Data pipelinerecords_processed / records_arrivedrecords_within_SLA / total_records
Storagedata_intact / data_storedreads_under_threshold / total_reads

Latency SLI использует bucket-счётчики, а не percentile

Latency SLO («99% запросов под 200мс») звучит как percentile, но реализуется как счётчик. Prometheus histogram на пороге SLO даёт это напрямую:

fast_requests = http_request_duration_seconds_bucket{le="0.2"}
latency_sli = sum(rate(fast_requests[1h])) / sum(rate(http_request_duration_seconds_count[1h]))

histogram_quantile не нужен — и нет погрешности оценки, которая загрязняла бы бюджет. Именно поэтому RED-Duration histogram обязан иметь границу bucket’а ровно на пороге SLO: без неё SLO нельзя оценить без аппроксимации.

Что считается «успехом»: границы хорошего SLI

Определение успеха иногда тоньше, чем кажется. Для HTTP API очевидное — 2xx-ответ, но 2xx с пустым телом или с устаревшими данными уже не success. Для gRPC — статус OK, но client-side timeout без серверного ответа технически не отказ сервера. Зрелые команды описывают определение явно: «success = HTTP 200 AND response body non-empty AND processing latency < 1s» — и инструментируют все три проверки.

Что не входит в SLI: out-of-scope

SLO считается над определённой совокупностью трафика. Стандартные out-of-scope категории:

  • Запросы из load test и pen test (помечены header’ом или IP-диапазоном)
  • Запросы от известных ботов и сканеров
  • Запросы во время запланированных maintenance window
  • Запросы, отброшенные rate-limit’ом на границе

Эти категории явно фиксируются в SLO-документе — иначе каждый postmortem превращается в спор о том, считать ли конкретный инцидент против бюджета. Большинство SLO-платформ поддерживают exclusion-фильтры через label’ы.

Выбор SLO-цели

SLO-цель — бизнес-решение, не инженерное. Вопрос: «какой минимальный уровень надёжности пользователи примут, прежде чем заметят и начнут жаловаться?» Инженерия отвечает: «какая минимальная архитектура это обеспечивает?»

SLO-цели и что стоит каждая девятка
99% SLO, 30 дней
7.2 часа допустимого downtime
99.9% SLO, 30 дней
43.2 минуты
99.95% SLO, 30 дней
21.6 минут
99.99% SLO, 30 дней
4.3 минуты
99.999% SLO, 30 дней
~26 секунд
Рост инженерных затрат за девятку
3–10x

Паттерн:

  • 99% → 99.9%: добавить мониторинг и базовый алертинг
  • 99.9% → 99.99%: добавить multi-region с автоматическим failover
  • 99.99% → 99.999%: добавить N+2-избыточность, chaos engineering, 24/7 on-call, просыпающийся за минуты

Полная арифметика error budget

После определения SLO бюджет становится конкретным:

error_budget = (1 − SLO) × total_events_in_window

Для 99.9% SLO за 28 дней при 1M запросов/день:

  • Total events = 28,000,000
  • Budget = 0.001 × 28,000,000 = 28,000 упавших запросов

По мере накопления отказов: budget_remaining = budget_total − failures_so_far

Burn rate в любой момент: burn_rate = current_error_rate / (1 − SLO)

При 0.1% error rate и 99.9% SLO: burn rate = 0.001 / 0.001 = 1x (устойчиво). При 1.44% error rate: burn rate = 0.0144 / 0.001 = 14.4x (бюджет закончится за 2 дня).

Почему 28 дней, а не «этот календарный месяц»

Календарные месяцы различаются (28–31 день) и создают cliff effect: плохая неделя в конце февраля по-другому бьёт по бюджету, чем та же неделя в конце марта. 28-дневное rolling window (четыре полные недели) решает оба: всегда покрывает одинаковую длину, включает полный цикл будни/выходные — паттерны трафика нормализуются.

Почему это работает

Rolling window — также причина, почему SLO-цели нужно начинать свободными и ужесточать ежеквартально, а не ставить жёстко в день первый. Консервативное начальное SLO даёт команде время увидеть реальный базовый error rate, понять паттерн трафика и правильно инструментировать счётчики — до того, как они несут ответственность за число, которое либо недостижимо, либо тривиально лёгкое.

Викторина

Какой из вариантов является хорошим SLI для request-driven API?

Викторина

99.9% availability SLO за 28 дней, 1M запросов/день. Команда на 14-м дне, 6,000 упавших запросов. Как с бюджетом?

Викторина

Почему 28-дневное rolling window предпочтительнее календарного месяца?

Вспомните перед уходом
  1. 01
    Почему SLI должен быть выражен как отношение, а не как абсолютный счётчик или машинная метрика?
  2. 02
    Почему latency SLI требует границы bucket'а histogram ровно на пороге SLO?
  3. 03
    Как выбрать SLO-цель?
Итог

Хороший SLI — отношение good events к total events, всегда в [0%, 100%], всегда отслеживающее то, что пользователи испытывают, никогда не машинная метрика типа CPU или длины очереди. Latency SLI использует histogram bucket-счётчики на пороге SLO, а не оценки histogram_quantile — чтобы арифметика бюджета была точной. SLO-цель — бизнес-решение: бери самую низкую надёжность, которую терпят пользователи, потому что каждая лишняя девятка умножает инженерные затраты в 3–10 раз. Используй 28-дневное rolling window для нормализации паттернов трафика. Budget = (1 − SLO) × total_events; burn rate = current_error_rate / (1 − SLO). Начинай свободно, ужесточай ежеквартально.

Связанные уроки
встречается в167
Продолжить восхождение ↑Multi-window multi-burn-rate-алертинг: почему AND лучше OR
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.