SLO и бюджет ошибок: почему «99,9 %» без окна не значит ничего
Одна и та же цель означает 43 минуты в месяц и полторы минуты в сутки. Урок разбирает арифметику окна, показывает, что незаметный инцидент съедает бюджета больше заметного, и объясняет, почему выбор между календарным и скользящим окном — это выбор правила, по которому кончается заморозка выкаток.
Полное техническое изложение
TL;DR
Надёжность считают долей, а обещают — уровнем этой доли за названный срок. Из тысячи запросов 990 успешных — это доступность 99 %. Обещание «мы держим 99 %» назначает уровень, а всё, что ниже уровня, — это то, сколько плохого обещание допускает: десять запросов из тысячи. Пока не сказано, за какой срок считается доля, такое обещание можно понять как угодно.
Отсюда главное следствие: одно и то же число означает разные вещи, а дороже всего оказывается то, чего никто не заметил. Арифметика: 99,9 % — это 43,2 минуты за 30 дней и 1,4 минуты за сутки. А цена инцидентов расставляет их не так, как ощущение: полная недоступность на 10 минут — 23 % месячного бюджета, а два процента ошибок в течение суток, которых никто не увидит глазами, — 67 %.
Дальше — единицы, окна и границы. Единица бюджета ошибок следует из SLI: при доступности, считаемой по запросам, бюджет удобно считать в неуспешных запросах — при 1000 запросов в секунду и цели 99,9 % за 30 дней это 2 592 000 запросов; при доступности, считаемой по времени, бюджет считают во времени. Половина запросов на час — 1 800 000 ошибок, или 69 % месячного бюджета. Окно — это правило, по которому кончается заморозка выкаток: после инцидента на 28-й день календарного месяца бюджет восстановится 1-го числа, а скользящее окно вернёт его только через 30 дней после самого инцидента. И всё это арифметика и модель, а не замер: числа выводятся из цели, окна и профиля инцидента при явно названных допущениях.
- запрос к сервису может закончиться успехом или ошибкой, и ошибки случаются всегда;
- доля считается делением: сколько успешных из скольких всего;
- выкатка новой версии — это риск: что-то может сломаться именно из-за неё.
- SLI, SLO, SLA и бюджет ошибок — все четыре слова разбираются здесь же, с самого начала;
- окна наблюдения, календарное против скользящего, выгорание бюджета.
Что здесь на самом деле спрашивают
Лестница обычно такая:
- «Что такое SLI, SLO и SLA?» — разминка на терминологию.
- «Что означает 99,9 %?» — здесь выясняется, спросит ли собеседник про окно.
- «Как из SLO получается бюджет ошибок?» — начало содержания.
- «Что делать, когда бюджет исчерпан?» — вопрос про решение, а не про метрику.
- «Календарное окно или скользящее?» — вопрос, отделяющий тех, кто этим пользовался.
- «Почему нельзя просто поставить цель 100 %?» — вопрос про смысл бюджета.
Урок стоит на расчёте, а не на прогоне. Причина простая: бюджет ошибок — это арифметика над двумя числами, и всё, что в нём есть, выводится, а не измеряется. Скрипт печатает и исходные величины, и результат, поэтому каждое число здесь можно пересчитать самому.
База: четыре слова, которые обычно путают
Начнём с арифметики на пальцах, без единого термина.
Сервис получил 1000 запросов. Из них 990 закончились успехом, а десять — ошибкой. Значит, доступность сервиса на этой тысяче — 99 %, а «плохого» случилось десять запросов из тысячи. Всё, никакой другой математики в теме нет: остальное — договорённости о том, что считать, какого уровня хотеть и что делать, когда уровень не выдержан.
Теперь те самые четыре слова, каждое обычными словами.
SLI — что мы измеряем. Это сама величина: доля успешных запросов. Могла бы быть и другая: доля запросов быстрее 300 мс, доля успешно оформленных заказов. Пока не выбрана величина, спорить не о чем.
SLO — какого уровня мы хотим. Это цель по выбранной величине: «доля успешных запросов не ниже 99 %». Внутреннее решение команды, а не обещание внешнему миру.
Бюджет ошибок — сколько плохого мы себе разрешаем. Это то же самое число, повёрнутое другой стороной: если цель 99 %, то на тысяче запросов разрешено десять неуспешных. Не «десять ошибок — это плохо», а «десять ошибок оплачены заранее».
SLA — внешнее обязательство. То, что записано в договоре с клиентом, с последствиями за нарушение. Живёт отдельно от SLO и обычно мягче: внутреннюю цель держат строже, чем обещанное наружу, чтобы запас между ними оставался местом для инженерных решений, а не для юристов.
И вот главный вопрос урока: на какой тысяче? Доля 990 из 1000 посчитана на одной тысяче запросов. За час их будет одно количество, за месяц — совсем другое, и одна и та же цель на этих отрезках означает совершенно разные вещи.
Этого уже достаточно, чтобы ответить на базовый вопрос собеседования. Всё дальнейшее — про то, во что превращается цель, когда назван срок, в чём считается бюджет и что происходит, когда он кончается.
Механизм 1: цель без окна не имеет смысла
1. THE SAME TARGET, DIFFERENT WINDOWS
-------------------------------------
target 1d 7d 30d 90d
99.00% 14.4 min 1.7 h 7.2 h 21.6 h
99.50% 7.2 min 50.4 min 3.6 h 10.8 h
99.90% 1.4 min 10.1 min 43.2 min 2.2 h
99.99% 9 s 1.0 min 4.3 min 13.0 min
Прочитайте строку 99,9 % слева направо: 1,4 минуты за сутки, 10,1 минуты за неделю, 43,2 минуты за месяц, 2,2 часа за квартал. Одно обещание — и четыре разные величины.
Отсюда первое, что стоит уточнять в разговоре: «у нас три девятки» — это ещё не обещание. Три девятки в сутки — жёсткая цель, при которой один перезапуск с минутной паузой съедает большую часть суточного бюджета. Три девятки в квартал — цель, при которой можно позволить себе двухчасовую аварию раз в три месяца.
Отсюда же практический вывод про переговоры: если окно не названо, стороны понимают обещание по-разному и обнаружат это в первый же инцидент.
Механизм 2: единица бюджета следует из SLI
Бюджет ошибок — это «сколько плохого разрешено». Первый вопрос здесь — плохого в чём, и ответ не выбирают по вкусу: единица бюджета следует из SLI.
- SLI считается по запросам («доля успешных запросов») — бюджет удобно считать в неуспешных запросах.
- SLI считается по времени («доля минут, когда сервис работал») — бюджет считается во времени, в минутах недоступности.
В этом уроке SLI — доля успешных запросов, поэтому дальше всё считается в запросах, а минуты стоят рядом как перевод. Перевод верен только для полной недоступности: там каждая нерабочая минута — это все запросы этой минуты, и только поэтому 2 592 000 запросов можно назвать «43,2 минуты».
2. WHAT ONE INCIDENT COSTS
--------------------------
target 99.9%
window, days 30
requests in the window 2 592 000 000
error budget, requests 2 592 000
error budget, minutes of total outage 43.2 min
incident: 100% of requests fail for 10 min 600 000 requests = 23% of the budget
incident: 50% of requests fail for 60 min 1 800 000 requests = 69% of the budget
incident: 2% of requests fail for 1440 min 1 728 000 requests = 67% of the budget
Три инцидента, три совершенно разных ощущения — и цена, которая расставляет их не так, как ощущение.
Полная недоступность на десять минут — то, что заметят все, попадёт в новости внутреннего чата и потребует разбора. Стоит она 23 % месячного бюджета.
Два процента ошибок в течение суток — то, чего не заметит никто: графики почти ровные, отдельные пользователи повторили запрос и забыли. Стоит это 67 % — втрое дороже громкой аварии.
Отсюда главная мысль урока: бюджет измеряет не громкость, а объём. Он и нужен затем, чтобы уравнять в правах два вида ущерба, которые интуиция оценивает несопоставимо.
И заметьте, чем это сравнение вообще держится: обе аварии посчитаны в одной единице, в неуспешных запросах, потому что такова здесь SLI. Считай мы доступность по времени, тихую деградацию нечем было бы измерить — сервис-то отвечал все сутки, недоступным он не был ни минуты.
И отсюда практика: тихая деградация опаснее шумной, потому что её никто не торопится чинить. Обнаруживает её только счёт бюджета — не глаз и не дежурный.
Механизм 3: календарное окно против скользящего
Третий блок — про то, что происходит после инцидента.
3. CALENDAR WINDOW AGAINST ROLLING WINDOW
-----------------------------------------
budget for 30 days, requests 2 592 000
incident on day 28: 50% for 1 hour 1 800 000 requests
that is 69% of the budget
calendar window: the budget resets on the 1st
budget left on day 29 31%
budget left on day 31 (new month) 100%
rolling 30-day window: the incident stays for 30 days
budget left 1 day after the incident 31%
budget left 15 days after the incident 31%
budget left 29 days after the incident 31%
budget left 31 days after the incident 100%
Инцидент один. Разница — в том, когда снова можно выкатывать.
Календарное окно прощает по расписанию: авария 28-го числа стоит два дня осторожности, а 1-го бюджет полон. Это удобно для отчётности и создаёт понятный перекос: конец месяца — время рисковать, начало — время не выкатывать ничего важного, потому что «бюджет только начался».
Скользящее окно ничего не прощает по календарю: инцидент влияет ровно 30 дней, а потом выпадает из окна сам. Оно честнее описывает пережитое пользователем, но требует объяснять, почему сегодня выкатывать нельзя, а вчера было можно, хотя ничего не случилось.
Обе политики законны, и вопрос на собеседовании обычно не «какая правильная», а «понимаете ли вы, что выбор делаете не про метрику, а про правило окончания заморозки».
Глубже: зачем бюджет нужен и почему цель ставят ниже 100 %
Последний уровень — про смысл конструкции и её границы, а не про арифметику.
Бюджет ошибок превращает надёжность из спора в арифметику с общим ответом. Пока он есть, выкатывать можно: риск оплачен заранее. Когда он исчерпан, выкатки останавливают — не в наказание, а потому что дальнейший риск нечем покрывать.
Отсюда ответ на вопрос про 100 %. Цель в сто процентов означает нулевой бюджет, то есть запрет на любое изменение: каждая выкатка — риск, а платить за него нечем. Именно поэтому цель ставят ниже единицы намеренно — не потому, что не умеют лучше.
И отсюда же — почему бюджет считают по метрике, которую видит пользователь. Метрика «сервис отвечает на проверку» (следующий урок) прекрасно себя чувствует, пока пользователи получают ошибки; бюджет, посчитанный по ней, никогда не кончится и ничего не остановит.
Как отвечать на собеседовании
Короткий ответ: SLO — это цель по метрике плюс окно, а бюджет ошибок — то, сколько плохого эта цель разрешает в этом окне; считается он в тех же единицах, в которых считается сама метрика. 99,9 % за 30 дней при 1000 запросов в секунду и доступности, считаемой по запросам, — это 2 592 000 неуспешных запросов, что при полной недоступности равно 43,2 минуты; те же 99,9 % за сутки — 1,4 минуты.
Этого достаточно, чтобы ответить верно. Дальше — то, что добавляют, если собеседник копает.
Если интервьюер копает глубже
Хороший ответ отличают три вещи. Первая — вы сразу спрашиваете про окно, потому что без него цель не число. Вторая — вы знаете, что тихая деградация дороже громкой аварии: два процента ошибок за сутки стоят 67 % месячного бюджета против 23 % у десятиминутной полной недоступности. Третья — вы говорите, что бюджет существует ради решения: пока он есть, выкатки идут; когда кончился, останавливаются, и в этом весь смысл цели ниже ста процентов.
И одна вещь, на которой легко переусердствовать. Сказать «бюджет считают в запросах, а не в минутах» — значит выдать частный случай за правило. Единица бюджета следует из SLI: доступность, считаемая по запросам, даёт бюджет в неуспешных запросах; доступность, считаемая по времени, даёт бюджет во времени. Ошибка не в минутах как таковых, а в переводе одного в другое: «43,2 минуты» верны ровно настолько, насколько инцидент похож на полную недоступность, и именно поэтому тихая деградация в минутах не считается вовсе — сервис при ней не был недоступен ни минуты.
Дальше спросят
Чем SLO отличается от SLA?
SLO — внутренняя цель, по которой принимают решения о выкатках; SLA — внешнее обязательство с последствиями в договоре. Практика обычно такая, что внутренняя цель строже внешнего обязательства: запас между ними и есть место, где живут решения без юридических последствий.
Из этого следует ответ на вопрос «что если мы нарушили SLO»: ничего юридического, но выкатки останавливаются. Если же нарушено SLA — начинается разговор про компенсации, и это уже не инженерное решение.
По какой метрике считать бюджет?
SLI — это сама метрика: доля успешных запросов, доля запросов быстрее порога, доля успешных операций. SLO — цель по этой метрике плюс окно, за которое её считают, а бюджет считается в единицах этой же метрики: по запросам — значит в неуспешных запросах, по времени — значит во времени. Считать бюджет надо по SLI, который описывает опыт пользователя, и именно поэтому в определение SLI входит порог: «успешный» и «быстрее 300 мс» — разные метрики и разные бюджеты.
Метрика вида «сервис отвечает на проверку» для бюджета не годится: она может быть зелёной, пока пользователи получают ошибки, и посчитанный по ней бюджет никогда не кончится.
Что делать, когда бюджет исчерпан?
Останавливать выкатки того, что этот бюджет тратит, и заниматься причинами. Смысл не в наказании: изменения — главный источник риска, и когда платить за риск нечем, разумно перестать его создавать.
Полезно оговорить заранее, что именно останавливается: выкатки продукта — да; исправления, снижающие расход бюджета, — нет. Иначе правило превращается в запрет чинить.
Почему бы не поставить цель 100 %?
Потому что это нулевой бюджет и, следовательно, запрет на любое изменение: каждая выкатка создаёт риск, а покрывать его нечем. Цель в сто процентов означает не «мы очень надёжны», а «у нас нет права на изменение».
Есть и вторая причина: сто процентов нельзя измерить. Любая метрика имеет собственные пропуски и сбои сбора, и цель, равная пределу, ломается на первом же сбое измерительной системы.
Частые заблуждения
99,9 % — это понятная цель
Без окна — нет: арифметика даёт 1,4 минуты в сутки и 43,2 минуты за 30 дней из одного и того же числа. Пока окно не названо, стороны понимают обещание по-разному и обнаружат это в первый же инцидент.
громкая авария всегда дороже тихой деградации
Наоборот, чаще дешевле: полная недоступность на 10 минут — 23 % месячного бюджета, а два процента ошибок в течение суток — 67 %. Бюджет измеряет объём ущерба, а не громкость, и тихая деградация опаснее именно потому, что её никто не торопится чинить.
бюджет ошибок — это всегда разрешённое время простоя
Единица бюджета следует из SLI. Считаете доступность по времени — бюджет и есть время простоя. Считаете по запросам, как в этом уроке, — бюджет есть число неуспешных запросов: при 1000 запросов в секунду и цели 99,9 % за 30 дней это 2 592 000 запросов. Ошибка не в минутах, а в переводе одного в другое: «43,2 минуты» верны только для полной недоступности, а два процента ошибок за сутки в минутах простоя не видны вовсе.
календарное и скользящее окно — вопрос вкуса
Это разные правила окончания заморозки. После инцидента на 28-й день календарное окно вернёт бюджет 1-го числа, а скользящее — только через 30 дней после самой аварии. Один и тот же инцидент, два разных ответа на вопрос «можно ли выкатывать сегодня».
цель 100 % — это просто очень высокая планка
Это нулевой бюджет, то есть запрет на любое изменение: каждая выкатка создаёт риск, а покрывать его нечем. Плюс сто процентов нельзя измерить — у любой метрики есть собственные пропуски, и цель, равная пределу, ломается на первом сбое сбора.
бюджет можно считать по доступности сервиса для проверок
Тогда он никогда не кончится. Проверка отвечает и в тот момент, когда пользователи получают ошибки (следующий урок), поэтому бюджет считают по метрике, описывающей опыт пользователя: доля успешных запросов или доля запросов быстрее порога.
исчерпанный бюджет означает, что надо остановить всю работу
Останавливают то, что бюджет тратит, — выкатки продукта. Исправления, снижающие расход, не останавливают никогда, иначе правило превращается в запрет чинить. Об этом стоит договориться заранее, а не в момент аварии.
Практика
Две задачи. Сначала ответьте, потом сверьтесь с настоящим выводом: в обеих правильный ответ взят из прогона расчёта, а не назначен.
Практика · что напечатает
budget = budget_requests(TARGET, WINDOW_DAYS)
print(human_minutes(WINDOW_DAYS * 24 * 60 * (1 - TARGET)))
print(human_minutes(1 * 24 * 60 * (1 - TARGET)))
print(f"{incident_errors(1.0, 10) / budget * 100:.0f}")Практика · оцените
Проверка знаний
Что означает цель 99,9 % без указания окна?
Это не пересказ и не отдельный текст: всё ниже взято из самой статьи — её выжимка, заголовки разборов, колонка «на самом деле» и таблица версий. Поэтому разойтись со статьёй эти тезисы не могут.
Суть
- Надёжность считают долей, а обещают — уровнем этой доли за названный срок. Из тысячи запросов 990 успешных — это доступность 99 %. Обещание «мы держим 99 %» назначает уровень, а всё, что ниже уровня, — это то, сколько плохого обещание допускает: десять запросов из тысячи. Пока не сказано, за какой срок считается доля, такое обещание можно понять как угодно.
- Отсюда главное следствие: одно и то же число означает разные вещи, а дороже всего оказывается то, чего никто не заметил. Арифметика: 99,9 % — это 43,2 минуты за 30 дней и 1,4 минуты за сутки. А цена инцидентов расставляет их не так, как ощущение: полная недоступность на 10 минут — 23 % месячного бюджета, а два процента ошибок в течение суток, которых никто не увидит глазами, — 67 %.
- Дальше — единицы, окна и границы. Единица бюджета ошибок следует из SLI: при доступности, считаемой по запросам, бюджет удобно считать в неуспешных запросах — при 1000 запросов в секунду и цели 99,9 % за 30 дней это 2 592 000 запросов; при доступности, считаемой по времени, бюджет считают во времени. Половина запросов на час — 1 800 000 ошибок, или 69 % месячного бюджета. Окно — это правило, по которому кончается заморозка выкаток: после инцидента на 28-й день календарного месяца бюджет восстановится 1-го числа, а скользящее окно вернёт его только через 30 дней после самого инцидента. И всё это арифметика и модель, а не замер: числа выводятся из цели, окна и профиля инцидента при явно названных допущениях.
На самом деле
- Без окна — нет: арифметика даёт 1,4 минуты в сутки и 43,2 минуты за 30 дней из одного и того же числа. Пока окно не названо, стороны понимают обещание по-разному и обнаружат это в первый же инцидент.
- Наоборот, чаще дешевле: полная недоступность на 10 минут — 23 % месячного бюджета, а два процента ошибок в течение суток — 67 %. Бюджет измеряет объём ущерба, а не громкость, и тихая деградация опаснее именно потому, что её никто не торопится чинить.
- Единица бюджета следует из SLI. Считаете доступность по времени — бюджет и есть время простоя. Считаете по запросам, как в этом уроке, — бюджет есть число неуспешных запросов: при 1000 запросов в секунду и цели 99,9 % за 30 дней это 2 592 000 запросов. Ошибка не в минутах, а в переводе одного в другое: «43,2 минуты» верны только для полной недоступности, а два процента ошибок за сутки в минутах простоя не видны вовсе.
- Это разные правила окончания заморозки. После инцидента на 28-й день календарное окно вернёт бюджет 1-го числа, а скользящее — только через 30 дней после самой аварии. Один и тот же инцидент, два разных ответа на вопрос «можно ли выкатывать сегодня».
- Это нулевой бюджет, то есть запрет на любое изменение: каждая выкатка создаёт риск, а покрывать его нечем. Плюс сто процентов нельзя измерить — у любой метрики есть собственные пропуски, и цель, равная пределу, ломается на первом сбое сбора.
- Тогда он никогда не кончится. Проверка отвечает и в тот момент, когда пользователи получают ошибки (следующий урок), поэтому бюджет считают по метрике, описывающей опыт пользователя: доля успешных запросов или доля запросов быстрее порога.
- Останавливают то, что бюджет тратит, — выкатки продукта. Исправления, снижающие расход, не останавливают никогда, иначе правило превращается в запрет чинить. Об этом стоит договориться заранее, а не в момент аварии.
Что разобрано
- Что здесь на самом деле спрашивают
- База: четыре слова, которые обычно путают
- Механизм 1: цель без окна не имеет смысла
- Механизм 2: единица бюджета следует из SLI
- Механизм 3: календарное окно против скользящего
- Глубже: зачем бюджет нужен и почему цель ставят ниже 100 %
- Как отвечать на собеседовании
- Дальше спросят
- Частые заблуждения
- Практика
- Проверка знаний
Источники и что читать дальше
1 ИСТОЧНИК
- Расчёт этого урока: модель бюджета ошибокИсточник. У этого урока нет внешнего первоисточника, и это сказано прямо: всё, что в нём есть, — арифметика, выводимая из двух чисел (цель и окно), плюс модель инцидента с объявленными допущениями. Допущения: постоянный поток 1000 запросов в секунду круглые сутки, прямоугольный инцидент, бюджет считается по доле неуспешных запросов, а не по времени недоступности, скользящее окно сдвигается посуточно. Прогон печатает и исходные величины, и результат, поэтому расчёт можно пересчитать целиком./ru/bench/slo/budget.py