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

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

Native histograms, SLO и паттерны production-сбоев

Суть Native (exponential) histograms устраняют ручную настройку бакетов. Duration и Errors из RED напрямую питают SLO error budget. Реальные production-сбои — Cloudflare, GitHub, Stripe, Discord — каждый сводится к конкретному пропущенному RED+USE сигналу.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 16 min

GitHub, 2023: SLO-алерт на задержку code-search многократно срабатывал без реакции. Расследование обнаружило: алерт был настроен на среднюю задержку — фикс бага, поднявший p99 с 200 мс до 800 мс, едва сдвинул среднее. SLO был переработан на multi-window p99 burn-rate алерты по паттерну Google SRE Workbook. Следующий инцидент был пойман менее чем за 4 минуты.

Native histograms (Prometheus 2.40+)

Классические гистограммы требуют выбора границ бакетов во время инструментации. Если распределение задержки сервиса смещается — например, медленный путь внезапно начинает доминировать в диапазоне 1–5 с — нужен повторный деплой с другими бакетами.

Native histograms (Prometheus 2.40+, также называемые exponential histograms в OTel) используют логарифмическую шкалу с динамически адаптирующимся разрешением. Каждое наблюдение помещается в бакет шириной ~1% относительной точности — e^(2^-scale) — без какого-либо статического списка границ. Преимущества:

  • Никакой ручной настройки бакетов.
  • Равномерная точность p99 по всему диапазону задержки (не только вблизи SLO).
  • Аналогичная стоимость хранения по сравнению с хорошо настроенной классической гистограммой.
  • Полная совместимость с PromQL: histogram_quantile работает так же.

Exponential histograms OTel работают идентично и являются дефолтом для новой инструментации метрик в OTel SDK.

Совместимость: некоторые старые storage-бэкенды (Cortex < 1.15, Thanos < 0.32) требуют обновления версий для чтения native histograms. Проверь storage-слой перед переходом.

Тип гистограммыНастройка бакетовТочность p99Совместимость
Классическая (фиксированные бакеты)Ручная, per-serviceХорошая только вблизи SLOУниверсальная
Native / exponentialНе нужна~1% вездеPrometheus 2.40+, дефолт OTel SDK
Summary (per-replica)НетКорректная per-replica, неверная агрегированнаяНельзя агрегировать по репликам

Почему усреднение p99 по репликам неверно

Усреднение предварительно вычисленных перцентилей (summary-метрики) по репликам — известный антипаттерн:

Пример: реплика A обслуживает 100 запросов, все по 100 мс. Реплика B обслуживает 100 запросов, все по 1000 мс. p99 у A = 100 мс; p99 у B = 1000 мс; их среднее = 550 мс. Истинный p99 объединённых 200 запросов = 1000 мс (ранг 199 из 200, выше 99-го перцентиля). Среднее ошибается почти вдвое.

Правильный паттерн: гистограммы эмитируют per-replica счётчики бакетов; sum by (le) (rate(...)) агрегирует их во время запроса; histogram_quantile вычисляет истинный fleet-wide перцентиль из агрегированных счётчиков. Точность ±половина бакета. Никакой изоляции по репликам.

RED питает SLO error budget

SLO — это обещание: 99,9% запросов успешно завершаются в пределах 200 мс за 30 дней. Duration и Errors из RED — это именно те метрики, которые наполняют это обещание.

  • SLO по доступности: 1 - rate(errors[window]) / rate(total[window]) — «99,9% запросов не должны возвращать 5xx»
  • SLO по задержке: histogram_quantile(0.99, ...) &lt; 0.200 — «99-й перцентиль должен быть ниже 200 мс»
  • Error budget: оставшиеся минуты или количество запросов до нарушения SLO за месяц.

Без RED-инструментации у тебя нет SLO — есть желание.

Multi-window burn-rate alerting (Google SRE Workbook): алертить, когда error budget сжигается слишком быстро одновременно на двух окнах:

  • 1-часовое окно (fast burn): ловит внезапные всплески (неудачный деплой).
  • 6-часовое окно (slow burn): ловит медленные регрессии, которые пороговые алерты пропускают.

Пороговый алерт на абсолютное значение p99 («сработать если p99 > 200 мс») пропускает медленные регрессии (p99 растёт со 150 до 190 мс за две недели, всегда ниже порога) и выдаёт false positive при кратких всплесках. Burn-rate алерты ловят оба сценария.

Паттерны production-сбоев в RED+USE

GitHub 2023 (алерт на среднюю задержку): SLO-алерт на среднюю задержку. Регрессия подняла p99 с 200 до 800 мс; среднее сдвинулось с 45 до 55 мс. Алерт не сработал. Фикс: переход на p99 burn-rate алерты с 1h коротким + 6h длинным окнами по SRE Workbook.

Cloudflare 2022 (cardinality explosion): Новый label на request_duration вызвал OOM Prometheus-серверов. Задержка вычисления правил выросла с 100 мс до 4+ с, маскируя алерты сервисов. Собственная метрика Prometheus prometheus_tsdb_head_series была ведущим сигналом — но алерта на неё не было. Фикс: per-team cardinality budget, принудительный в CI; мета-мониторинг собственного RED Prometheus.

Stripe 2024 (PSI memory pressure невидима для free-RAM): Webhook-воркер завис на 11 минут. Дашборды free-RAM показывали 500 МБ свободных. PSI memory full был на уровне 90% — ядро трэшило reclaim. Фикс: перенос saturation-алертинга с MemAvailable &lt; threshold на PSI-алертинг; следующий инцидент пойман за 30 секунд.

Discord 2023 (рост задержки вычисления правил): Рефактор перенёс hot label с одной метрики на две. Cardinality удвоилась молча. Задержка вычисления правил Prometheus выросла с 100 мс до 4 с за две недели, задерживая алерты во время инцидента, видимого пользователям. Фикс: задержка вычисления правил добавлена как первоклассная панель в мета-мониторинг дашборд.

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

Самореференциальная наблюдаемость: Prometheus сам эмитирует RED- и USE-метрики. Ключевые self-метрики Prometheus, за которыми нужно следить: prometheus_tsdb_head_series (рост cardinality), prometheus_engine_query_duration_seconds_p99 (задержка запросов), prometheus_rule_evaluation_duration_seconds_p99 (задержки алертов). Каждый observability-слой — OTel Collector, Fluent Bit, Vector — эмитирует собственный RED. В зрелом стеке каждый слой наблюдаемости сам наблюдается. Режим отказа ненаблюдаемого monitoring-слоя — молчаливая ошибка: твои сервисы выглядят нормально, но мониторинговый пайплайн перестал доставлять их данные 20 минут назад.

Викторина

Команда использует Prometheus summary (предварительно вычисленный p99 per-replica) и усредняет их для получения fleet-wide p99. Почему это математически неверно?

Викторина

Пороговый алерт срабатывает когда p99 > 200 мс. p99 дрейфует с 140 мс до 185 мс за три недели (никогда не пересекая 200 мс). SLO позволяет 99,9% запросов выполняться в пределах 200 мс. Что пороговый алерт пропускает, что поймал бы burn-rate алерт?

Вспомните перед уходом
  1. 01
    Что такое native (exponential) histogram и какую проблему он решает по сравнению с классическими гистограммами?
  2. 02
    Как RED связан с SLO error budget? Какова формула SLO по задержке?
  3. 03
    Каковы два burn-rate окна в multi-window alerting и что каждое из них ловит?
Итог

Native (exponential) histograms, доступные в Prometheus 2.40+ и как дефолт OTel SDK, используют логарифмическую шкалу бакетов при ~1% относительной точности, устраняя ручную настройку бакетов, необходимую для классических гистограмм. Гистограммы Duration и счётчики Errors из RED — прямой субстрат для измерения SLO: SLO по доступности — 1 - error_rate, SLO по задержке — histogram_quantile(0.99) &lt; цель. Multi-window burn-rate alerting (1h короткое + 6h длинное окна) ловит и внезапные регрессии, и медленный дрейф, которые пороговые алерты пропускают — поимка медленного типа была тем, что потребовал post-mortem инцидента GitHub 2023. Каждый крупный production-сбой в этом блоке — Cloudflare 2022, GitHub 2023, Stripe 2024, Discord 2023 — сводился к одному конкретному пропущенному RED или USE сигналу: cardinality explosion невидимый без self-мониторинга Prometheus, средняя задержка маскирующая p99, free-RAM невидимый для PSI memory pressure и рост задержки вычисления правил маскирующий алерты. Самореференциальная наблюдаемость — мониторинг самого monitoring-пайплайна с той же RED+USE дисциплиной — последняя линия защиты.

Связанные уроки
встречается в167
Продолжить восхождение ↑RED и USE: тест с выбором ответа
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.