Рассмотрим систему, которая обрабатывает запрос только при успешной работе двух независимых зависимостей. Как их доступность влияет на доступность сервиса?
Если обе зависимости обязательны для каждого запроса, доступность сервиса примерно равна произведению их доступностей, а не их среднему значению. При доступности каждой зависимости 99,9% итоговая доступность составит 99,9% × 99,9% = 99,8001%, то есть около 99,8%.
Это верно только при предположении независимости отказов и одинаковом интервале измерения. Общие причины отказов, каскадные эффекты и особенности архитектуры могут сделать фактический результат хуже или лучше расчётного.
Такой расчёт возник из практики анализа надёжности систем, состоящих из последовательно необходимых компонентов. В последовательной схеме отказ любого обязательного элемента делает недоступной всю цепочку.
Подход позволяет заранее увидеть, что добавление обязательных зависимостей ухудшает достижимую надёжность сервиса. Поэтому архитекторы используют резервирование, локальные деградированные режимы и уменьшение количества синхронных зависимостей.
Предположим, сервис обращается к базе данных и отдельному сервису авторизации. Если любой из них недоступен, пользовательский запрос завершается ошибкой.
Интуитивно можно ошибочно считать, что две зависимости с доступностью 99,9% сохраняют доступность около 99,9%. На самом деле у запроса появляются две независимые возможности завершиться отказом, поэтому общий бюджет ошибок увеличивается.
Неверный расчёт приводит к завышенному SLO сервиса, недостаточному резервированию и неожиданному превышению бюджета ошибок. Особенно заметен эффект при длинной цепочке: произведение нескольких значений меньше каждого отдельного значения.
Пусть A и B — события доступности двух обязательных зависимостей. Запрос успешен только при одновременном наступлении обоих событий, поэтому при независимости отказов вероятность успеха равна:
P(успех) = P(A) × P(B).
Для двух зависимостей с доступностью 0,999 результат равен 0,998001, или 99,8001%. Недоступность при этом составляет примерно 0,1999%, что почти вдвое больше недоступности одной зависимости.
Для последовательной цепочки из нескольких обязательных компонентов доступности перемножаются. Однако это не универсальный закон для любой архитектуры: он описывает конкретную модель с обязательными компонентами, независимыми событиями и одинаковым способом измерения доступности.
Независимость часто нарушается. Зависимости могут использовать один кластер, сеть, регион, систему идентификации, команду эксплуатации или общий лимит ресурсов. Такой общий фактор вызывает коррелированные отказы, и произведение индивидуальных доступностей становится оптимистичной оценкой.
Если зависимость необязательна, сервис может продолжить работу в деградированном режиме. Тогда нужно считать не только бинарную доступность, но и долю запросов с полноценным или ограниченным результатом, явно определив это в SLI и SLO.
Резервирование меняет структуру расчёта. Если есть два независимых экземпляра, достаточно работы хотя бы одного, и вероятность успеха при одинаковой доступности каждого равна 1 − (1 − A)². Но это преимущество реализуется только при независимых отказах, корректном обнаружении неисправности и способности оставшегося экземпляра выдержать нагрузку.
Платёжный сервис зависел от отдельного сервиса проверки лимитов и от базы данных заказов. Каждый компонент имел заявленную доступность 99,9%, поэтому исходное SLO платёжного сервиса установили также на уровне 99,9%.
Рассматривались три варианта. Первый — ничего не менять: он был самым дешёвым, но не устранял математическое и архитектурное ограничение. Второй — добавить резервный экземпляр каждой зависимости: это повышало доступность, но требовало проверки независимости отказов, автоматического переключения и контроля нагрузки после отказа. Третий — разрешить ограниченный режим для уже известных клиентов, когда проверка лимита временно недоступна: это улучшало пользовательский результат, но требовало строгих ограничений риска и последующей сверки.
Выбрали комбинацию резервирования и контролируемой деградации. Критические операции по-прежнему требовали обеих проверок, а некритичные могли временно использовать безопасно закэшированный результат с ограниченным сроком действия. SLO разделили по типам операций, чтобы доступность полноценного и деградированного результата не смешивалась в одну вводящую в заблуждение метрику.
Ответ: Простое произведение доступностей больше неприменимо, потому что событие отказа одной зависимости связано с событием отказа другой. Например, общий сетевой сегмент может вывести их из строя одновременно. Нужно анализировать совместную вероятность отказа, общие точки отказа и результаты отказовых испытаний; индивидуальные SLO сами по себе не раскрывают такую зависимость.
Ответ: Формула выигрыша предполагает независимые отказы, своевременное обнаружение неисправности и достаточную ёмкость оставшегося экземпляра. Общий источник питания, общий регион или ошибка в маршрутизации могут отказать сразу у обоих экземпляров. Кроме того, после переключения оставшийся экземпляр может перегрузиться, вызвав вторичный отказ.
Ответ: Сначала нужно определить, какой результат считается успешным для каждой категории операций. Полноценный ответ и безопасный деградированный ответ следует измерять раздельно, иначе одна агрегированная метрика скроет ухудшение качества. Для каждой категории задают собственный SLI и SLO, а правила деградации должны ограничивать риск устаревших данных, некорректных решений и последующей рассинхронизации.