Перейти к содержимому

«Наш SLO — 99.95%» — типичная декларация после квартального планирования. Теперь посмотрим на граф сервиса: четыре зависимости с SLA поставщика 99.9% (auth, платежи, CDN, управляемая база), два внутренних сервиса с 99.99%, общий слой DNS и TLS. Простая арифметика для последовательного пути: 0.999⁴ × 0.9999² × 0.9999 ≈ 0.9957 — достижимый потолок 99.57%, а не 99.95%. Composite SLO Methodology — это математика систем из многих компонентов: место, где «хочется четыре девятки» встречается с суммой зависимостей, и дальше приходится либо снижать обещание, либо добавлять резервирование, либо честно признать имеющуюся планку. Я регулярно вижу команды, которые объявляют SLO без этой арифметики, — и первый же отказ зависимости сжигает квартальный error budget целиком.

Граница: SLO Engineeringкак формулировать SLO для одного компонента (SLI, цель, окно); этот лист — как складывать SLO системы из многих частей. Vendor Reliability — SLA поставщиков как входные данные для расчёта; там же про надёжность внешних зависимостей вообще. Resilience Patterns — что делать, чтобы пробить математический потолок резервированием и плавной деградацией.

Главный навык на уровне L5 — отличать последовательные зависимости от параллельных и применять правильную формулу. Я регулярно вижу команды, которые перемножают SLA всех зависимостей подряд. Но если у CDN есть запасной путь на origin, это параллель — отказ наступает только при двойном отказе, и формула другая: 1 − (1 − SLA_cdn)(1 − SLA_origin). Различить эти два случая — не формальность, а разница между 99.5% и 99.99% на одном и том же наборе компонентов. Если граф нарисован, формула механическая; если граф «в голове», расчёт всегда оптимистичнее реальности.

L4

  • Понимает базовую арифметику: для последовательных зависимостей собственный SLO не выше произведения их SLA; знает, что SLA поставщика — нижняя граница, а не ожидаемое поведение.
  • Находит критический путь по графу своего сервиса: какие зависимости лежат на пути запроса для каждой пользовательской операции.
  • Считает арифметику для своего сценария: последовательный путь, параллельные компоненты, общая инфраструктура.
  • Знает, где стоит точка измерения его SLI и что остаётся за её пределами: провайдерские стыки, глобальная маршрутизация, защита от DDoS перед периметром. Всё, что до этой точки, в расчёт команды не входит.

L5

  • Различает последовательные и параллельные зависимости и применяет правильные формулы. Параллель: 1 − ∏(1 − SLA_i), последовательность: ∏ SLA_i.
  • Берёт SLA поставщика как нижнюю границу, а не как ожидаемую доступность. SLA — это порог, ниже которого поставщик готов вернуть деньги; фактическая доступность бывает выше, но планируют по договору, а не по наблюдениям.
  • Разделяет зависимости на обязательные и best-effort: система наблюдаемости, конвейер логов, асинхронная аналитика в пользовательский расчёт не входят, их падение пользователь не замечает; auth, платежи, база — входят.
  • Применяет многооконный алертинг по скорости сжигания на сценарий, а не на сервис. SLI собирается на уровне сценария (синтетика, данные из браузера, бизнес-событие), а не только на отдельной ручке.
  • Проверяет заявленную классификацию зависимостей данными: сопоставляет burn rate зависимости со своим, гоняет game day по подозрительным рёбрам графа. Слова разработчиков про «слабую связь» — гипотеза, а не факт.
  • Умеет калибровать цель эмпирически, когда у зависимостей нет ни SLA, ни SLO: сверху вниз от жалоб пользователей и шума алертов, а не снизу вверх от арифметики.
  • Вовремя останавливает уточнение расчёта: спрашивает, какое решение изменится от следующего знака после запятой, и, если ни одно, оставляет грубую оценку.

L6+

  • Держит портфель сценариев на уровне организации: какие получают обязательства по SLO, какие остаются без них. Не каждый сценарий стоит SLO, и обоснование выбора записано явно.
  • Использует расчёт как вход для решений по мощностям и деньгам: где резервирование оправдано (сценарий, на котором зарабатывают), где нет (админка с тремя пользователями). Связь с Cloud Cost Control прямая.
  • Пересчитывает арифметику после каждого крупного изменения в зависимостях: сменился поставщик, убрали резервирование, поменялась схема и вырос веер вызовов. Без пересчёта расчёт протухает за квартал.
  • Держит две модели одновременно: арифметика отвечает на вопрос «что можно обещать», продуктовая разметка error budget — на вопрос «чей бюджет горит при каскаде». Смешение этих вопросов даёт большинство споров на ревью SLO.
  • Держит модель дешёвой в сопровождении и понятной продуктовым командам. Расчёт, который умеет защитить только его автор, на масштабе организации не живёт: его перестают обновлять, а споры о его корректности съедают больше времени, чем сама работа над доступностью.
  • Alex Hidalgo — Implementing Service Level Objectives (O’Reilly, 2020). Единственная книга, где вероятностной стороне SLO отведена отдельная глава, а не абзац. Рекомендую: если выбирать одну ссылку из списка, то эту.
  • Betsy Beyer et al. (eds) — The Site Reliability Workbook (O’Reilly, 2018), глава 2 «Implementing SLOs». Раздел про зависимости сверху и снизу — подход Google. Тоже рекомендую, хотя по составным целям это заметно мельче, чем у Идальго.
  • Betsy Beyer et al. (eds) — Site Reliability Engineering (O’Reilly, 2016), глава 3 «Embracing Risk». Рекомендую, хотя напрямую про сложение здесь ничего нет: целевая доступность — решение с разменами, а не красивое число, и без этого арифметика ниже повисает в воздухе.
  • Alex Ewerlöf — Composite SLO. Разбор с конкретными формулами и схемами: как складывать SLO компонентов и почему наивное перемножение врёт. Рекомендую читать сразу после Идальго: там теория, здесь практика.
  • Google Cloud — SRE fundamentals: SLIs, SLAs and SLOs. По сложению неглубоко, зато канонический источник по словарю. Рекомендую как место, куда отправлять спорящих о терминах.
  • Marc Brooker — личный блог (AWS Principal Engineer). Отдельной статьи именно про сложение SLA у него нет, но разборы вероятностного поведения распределённых систем рекомендую как фон: из них понятно, почему считать в лоб нельзя.
  • Мой разбор — SLO как чертёж архитектуры (jtprog.ru, май 2026). Формул сложения там нет, зато разобрана ошибка, из которой нужда в них вырастает: раздел про ловушку среднего по системе показывает на кейсе маркетплейса, как один индикатор на весь сценарий прячет деградацию отдельного шага. Стоит прочитать до разбора Ewerlöf, если составной расчёт пока кажется теорией.
  • OpenSLO — независимая от вендоров спецификация SLO в YAML; составные цели описываются через objectives[] с несколькими SLI. Используется в Sloth, Pyrra и Nobl9, и рекомендую держаться этого формата, а не заводить свой YAML.
  • Sloth — SLO как код для Prometheus; правила многооконного алертинга по скорости сжигания генерируются автоматически. Составной SLO собирается из нескольких определений плюс свои recording rules.
  • Pyrra — альтернатива Sloth с более жёсткими умолчаниями. По моим наблюдениям, Sloth чаще берут туда, где уже что-то настроено, Pyrra — когда начинают с нуля.
  • Nobl9 — коммерческая платформа для SLO. Сам не работал, но по отзывам коллег поддержка составных целей из коробки здесь лучшая из доступных; рекомендую смотреть, если программа SLO для компании критична и бюджет на неё есть.
  • Пример Error Budget Policy из SRE Workbook — готовый шаблон политики от Google, рекомендую начинать с него, а не с чистого листа; отдельного репозитория с таким шаблоном у них нет, несмотря на распространённое заблуждение.
  • Анти-инструмент: расчёт в таблице Excel, который обновляют вручную раз в квартал. Это не инструмент, а приглашение к протухшей арифметике. Расчёт живёт в коде (OpenSLO, определения Sloth) и обновляется PR’ом вместе с графом зависимостей.

Главный публичный кейс — не отдельный инцидент, а опубликованные SLA самой AWS. У каждого сервиса своё число: S3 — 99.9% для стандартного хранения, EC2 — 99.99% на региональный парк машин, RDS — 99.95% для конфигурации с несколькими зонами. Соберём типовое веб-приложение в одном регионе: балансировщик (99.99%) → парк EC2 (99.99%) → RDS в двух зонах (99.95%) → S3 (99.9%) под статику. Последовательная арифметика даёт 0.9999 × 0.9999 × 0.9995 × 0.999 ≈ 0.9983. Это 99.83% — потолок, который AWS готова подтверждать компенсациями. Многие команды объявляют 99.95% и выше, не заглянув в эту арифметику. Я регулярно вижу архитектурные обсуждения «как нам достичь четырёх девяток», в которых сложение зависимостей не всплывает ни разу, — и цель остаётся либо реальной (если добавлены переключение между регионами, зоны, резервирование), либо мечтой (если это просто декларация поверх той же топологии). Один лист бумаги с этим расчётом перед объявлением SLO — час работы и год честности.

Прежде чем считать, нужен граф. Без явного критического пути расчёт превращается в произвольную сумму чужих SLA: рисуем граф, отмечаем, без чего пользователь реально страдает, и только потом берёмся за формулы.

SLA поставщика идёт в расчёт как пол, а не как потолок. Это число, за нарушение которого он готов вернуть деньги, а не его ожидаемая доступность и уж точно не ваш прогноз. Реальность обычно лучше договора. Планировать всё равно приходится по договору.

Зависимости делятся на обязательные и best-effort, и это деление стоит проговорить явно. Наблюдаемость, конвейер логов, асинхронная аналитика — их падение не означает, что пользователю плохо. Auth, платежи, база, CDN — означает. В расчёт входят только вторые, иначе потолок опускается без всякой причины со стороны пользователя.

Порядок работ — сначала очевидные дыры, потом третий знак. Если сервис недоступен час в день, точность арифметики не изменит ни одного решения. Уточнять расчёт окупается только тогда, когда фактическая доступность подошла к потолку и вопрос «где взять ещё девятку» стал настоящим.

И последнее: точка измерения совпадает с границей зоны ответственности. Пользователь видит одно число, в которое входят его собственный провайдер, глобальная маршрутизация и защита периметра от DDoS, — команда на это не влияет никак. Поэтому измерение начинается там, где начинается ответственность, и эта граница записана в SLO-документе явно.

Подробнее:

Последовательность против параллели — главное место ошибок. Распространённая ошибка — сложить все зависимости в одну формулу ∏ SLA_i. На деле, если у CDN есть запасной путь на origin, это параллель, и считается иначе: 1 − (1 − SLA_cdn)(1 − SLA_origin) ≈ 1 − 0.001 × 0.0001 = 99.99999%. Если у auth есть основной и резервный поставщик — то же самое. Если база живёт в двух зонах, параллель уже зашита внутрь SLA поставщика, и его 99.95% её учитывают. По моим наблюдениям, серьёзный расчёт для обычной команды — это день-два работы: нарисовать граф, разложить зависимости по типам, посчитать. На выходе появляется картина, которая меняет разговор на ревью SLO.

Составной SLO — это не «потолок 99.X%», а семейство целей по сценариям. Сервис обычно обслуживает несколько сценариев: вход, покупка, просмотр, обращение в поддержку. У каждого свой критический путь и своя арифметика. Вход может дать 99.95%, потому что зависимостей мало; покупка — 99.5%, потому что в цепочку встаёт платёжный провайдер; просмотр — 99.9%. Команда обещает не один SLO на сервис, а по одному на сценарий. Я регулярно вижу команды с единственным SLO на весь сервис, которые в день инцидента не могут ответить, какая часть продукта затронута.

Математика отвечает на вопрос про цель, error budget — на вопрос про ответственность. Самое сильное возражение, которое я слышал на этот лист: в продуктовой модели крупной компании каждый продукт держит свой SLO и отвечает за свой код, а каскадный отказ соседа сжигает бюджеты обоих сразу — и это честно отражает фактическую недоступность, включая инфраструктурную команду с её собственным SLO на базу. Зачем тогда вообще считать зависимости? Возражение справедливое, но отвечает оно на другой вопрос. Двойное сжигание — механизм учёта постфактум: инцидент уже случился, надо честно поделить его между владельцами. Арифметика зависимостей нужна до обещания: она говорит, какое число вообще имеет смысл называть при текущей топологии. Одно без другого даёт либо аккуратный учёт при фантазийной цели, либо честную арифметику без последствий для тех, кто её нарушил.

Наследование от инфраструктуры считают почти все, наследование от соседей — почти никто. «Нельзя запустить сервис с четырьмя девятками на железе с одной девяткой» звучит настолько очевидно, что вертикальная матрёшка (железо → платформа → сервис) действительно учитывается в большинстве команд, где я это видел. Горизонтальная — нет: сервисы того же уровня, от которых мой ответ зависит ровно так же, в арифметику не попадают, потому что они «наши, свои, рядом сидят». Очевидность правила не гарантирует его применения, и разрыв проходит именно по этой линии.

Когда у зависимостей нет SLO, цель калибруется от боли. Арифметика снизу вверх предполагает, что у каждой зависимости есть SLA или SLO. Реальность внедрения обычно другая: сервис-агрегатор собирает ответ из десятка мелких, ни у одного из них SLO нет и в ближайшие два квартала не появится, а закреплять качество обслуживания по всей цепочке — работа на год. Тогда работает встречный метод: взять цель «похоже на правду» и калибровать эмпирически по двум сигналам — алерты по скорости сжигания перестали шуметь, поток жалоб резко упал. Точка, где сигналы сходятся, и есть приблизительный максимум возможного при нынешней топологии. Метод грубый и не работает там, где сервисы активно переписывают, но это скорее хорошая новость: если цель не ловится месяцами, значит в цепочке есть нестабильное звено, и искать его полезнее, чем спорить о третьей девятке.

Граф со слов разработчиков врёт, и вскрывают это инциденты. Опрос «насколько жёстко вы зависите от этого сервиса» даёт классификацию, а не факт. Зависимость, названная слабой при обследовании, регулярно оказывается жёсткой по реальным данным: таймаут не выставлен, ретраи без бюджета, запасной путь написан и ни разу не проверен. Проявляется это на первом же серьёзном сбое той зависимости — то есть уже после того, как SLO объявлен и математика согласована. Отсюда практика: классификацию проверять сопоставлением сжигания у зависимости и у себя за квартал, подозрительные рёбра трогать инъекцией отказов на game day, а граф пересматривать после каждого инцидента, который показал связность, которой в документе не было.

Точность стоит дорого, и в этом её главная граница. Второе сильное возражение на этот лист — про цену: сложная модель съедает ресурсы не столько на сам расчёт, сколько на бесконечные споры о его корректности с разработкой и со всеми, кому потом жить с задачами по доступности. Мне рассказывали доведённый до абсурда случай: сервис лежит по часу в день, а команда ежедневно на созвоне спорит, как точнее измерить этот час. Считать надо было не простой, а стоимость самой дискуссии. Я согласен с выводом: грубая модель, понятная тем, кто не хочет глубоко влезать в тему, лучше точной, которую никто не принимает, а высвободившиеся руки полезнее направить на очевидные места, где доступность реально проседает. Практически это значит: девятки без дробей, округление вниз, одна страница вместо документа, пересчёт по событию (сменился поставщик, убрали регион), а не по календарю. Вкладываться в точность стоит в трёх случаях: цель выбирается вплотную к потолку; число уходит наружу в контракт с деньгами; надо решить, куда вложить бюджет на резервирование, и варианты сравнимы. Во всех остальных порядок величины закрывает вопрос. И признак, что модель пора упрощать, простой: спор о цифре идёт дольше, чем занял бы фикс той зависимости, вокруг которой спорят.

SLA поставщика берут пессимистично. Наблюдаемая доступность может держаться на 99.99%, а в договоре стоять 99.9% — в расчёт идёт договор. Поставщик может перестроить инфраструктуру, нагрузить соседних клиентов, поймать региональный инцидент: прошлый квартал ничего не обещает про следующий. Запас на его стороне освобождает ваш собственный бюджет под ваши же инциденты.

Пересчёт делается после каждого крупного изменения графа. Граф меняется чаще, чем кажется: сменили платёжного провайдера, закрыли второй регион ради экономии, поставили кеш перед базой. После каждой такой перемены арифметика считается заново, а обещание пересматривается. Я регулярно вижу команды, у которых документ с расчётом датирован полутора годами назад, а граф с тех пор менялся трижды.

Скорость сжигания меряется по сценарию, а не по компоненту. Классический многооконный алертинг часто строят на отдельных SLI: задержка и ошибки каждой ручки. Составной мир требует SLI уровня сценария: синтетический прогон, цепочка событий из браузера, бизнес-транзакция вроде «заказ оформлен». Алерт срабатывает, когда горит сценарий, то есть «пользователи действительно не могут купить», а не «одна из двенадцати ручек деградировала». По моим наблюдениям, зрелая программа SLO от начинающей отличается именно этим: сценарий как основной сигнал, компоненты — как диагностика.

  • SLO Engineeringкак формулировать SLO для одного компонента; этот лист — как складывать их для системы из многих. Читать вместе.
  • Vendor Reliability — SLA поставщиков как входные данные. Там ведут реестр, здесь им пользуются.
  • Resilience Patterns — что делать, чтобы пробить математический потолок: резервирование, плавная деградация, запасные пути. Именно они превращают последовательные зависимости в параллельные.
  • Capacity Planning — расчёт показывает, какие компоненты просят резервирования, а это уже решение по мощностям со своим сроком поставки.
  • Cloud Cost Control — резервирование ради лишней девятки стоит денег; размен считается рубль в рубль.
  • SLI-based Alerting / Symptom vs Cause Alerting — SLI уровня сценария требует алертинга по составному пути, а не только по компонентам.
  • SLO / Budget Review — ритуал, на котором расчёт пересматривается: что изменилось в графе, осталась ли арифметика честной, нужно ли двигать обещание.
  • Составной SLO для асинхронных и пакетных систем (TBD) — формулы для SLI по свежести и отставанию. Классическая теория покрывает онлайн; пакетная обработка (конвейеры Airflow и Dagster, потоки Kafka) — отдельная подобласть со своей математикой.
  • Вероятностный расчёт против худшего случая — сейчас всё считается по худшему случаю; вероятностный подход (Монте-Карло с распределением на каждую зависимость) точнее, но его почти никто не применяет. Подозреваю, дело не только в сложности инструментов: для большинства команд следующий знак после запятой не меняет ни одного решения, а цена споров о модели растёт быстрее её пользы. Если у вас Монте-Карло реально окупился — расскажите через PR, мне интересен именно случай, где точность что-то изменила.
  • Разложение SLO вниз — обратная задача: «нам нужно 99.95% для пользователя, какой бюджет отдать каждому компоненту». Она не аддитивна и требует оптимизации.
  • Стык составного SLO и политики бюджета — как несколько бюджетов по сценариям уживаются между собой (сжигание одного не должно блокировать выкатки другого). Сюда же вопрос про каскад: сбой соседнего продукта сжигает бюджет и у него, и у пострадавшего, и у инфраструктурной команды под ними — учёт честный, но замораживать релизы всем троим осмысленно не всегда.
  • Формализация калибровки от боли — эмпирический подбор цели по шуму алертов и потоку жалоб работает, но у меня нет для него ни процедуры, ни критерия остановки: сколько наблюдать, какой спад жалоб считать достаточным, когда признать, что цель недостижима и проблема в зависимости. Если у вас метод отлажен — расскажите через PR.
  • Я не уверен, как корректно учитывать коррелированные отказы: упал один регион облака — задеты все зоны внутри него, и арифметика перестаёт быть аддитивной. Идальго об этом упоминает, но канонического ответа не даёт. Если есть рабочая модель — расскажите через PR.