Всем привет, меня зовут Александр Москвин, я начальник управления эксплуатации X5 Облака в X5 Tech. У меня несколько зон ответственности, но важнейшая из них – это обеспечение доступности облачной инфраструктуры Х5.

Конечно, для того, чтобы управлять доступностью, необходимо оцифровать этот показатель. Статья родилась из жарких дебатов по целевым показателям доступности частного облака X5 и серии больших внутренних митапов, посвящённых этой теме. Кажется, что результатами стоит поделиться с сообществом, т. к. накопилась критическая масса материалов и выводов. Мысли  будут полезны менеджерам, принимающим решения, и solution-архитекторам для переговоров с заказчиками, лидам команд инфраструктуры и разработки. К сожалению, получился лонгрид, так как охватить все аспекты данной темы короткой статьёй не выйдет.

Доступность – очень важная и, одновременно, одна из самых спорных метрик в ИТ-мире. Особо жаркие споры возникают, когда требуется сформулировать некую метрику, которая описывает доступность большой системы, оказывающей услуги большому количеству пользователей на протяжении какого-то промежутка времени.

Очень актуален этот вопрос для сервисных подразделений, которые отвечают за большую развитую инфраструктуру: количество объектов под контролем измеряется тысячами, контрольные временные промежутки от месяца до года, количество изменений за этот год измеряется сотнями и тысячами. При этом необходимо предоставить всем понятную метрику, которой могут оперировать и инженеры, и архитекторы, и менеджеры среднего звена, принимающие решение, и топ-менеджеры, формирующие стратегии.

Вопрос рассматриваю, в основном, для доступности сервиса виртуальных машин как наиболее близкий мне пример, но подход можно применять вообще для любого сервиса: API, сайт и даже парикмахерские, службы такси и т. п.

Почему это сложный вопрос?

Даже для одного объекта определить состояние доступности не всегда просто.

Парикмахерская доступна (открыта), но все парикмахеры заняты. Или есть свободные парикмахеры, но нет свободных парикмахеров по мужским стрижкам.

Виртуальная машина недоступна для подключения по SSH, но запущенные сервисы всё равно работают, нельзя только подключиться.

Я не буду в статье погружаться в определение доступности каждого единичного объекта, просто скажу, что если объектов несколько, то задача становится ещё сложнее. Кроме того, как правило, можно всё-таки прийти к соглашению по вопросу «Что такое недоступность вот для этого конкретного объекта?».

Для больших систем, вообще говоря, полная недоступность – достаточно редкое состояние, обычно приходится говорить о деградации. Но и эту деградацию лучше корректно отражать в показателе доступности, для того чтобы результаты работы сервисной команды были прозрачны для всех потребителей услуги.

В больших и сложных системах полная недоступность – редкое состояние. Чаще приходится говорить о деградации
В больших и сложных системах полная недоступность – редкое состояние. Чаще приходится говорить о деградации

Доступность в момент времени

Начнём с простой ситуации – одна-единственная виртуальная машина. Очевидно, что доступность такого объекта в каждый момент времени можно охарактеризовать бинарным состоянием: либо виртуалка доступна, либо нет.

Такой подсчёт доступности вполне укладывается в одно из нескольких определений доступности:

Доступность информации – состояние информационных ресурсов автоматизированной системы, при котором пользователям гарантированно предоставляется доступ согласно выделенным правам.

Такое определение доступности отвечает только на один вопрос: "Прямо сейчас моя информационная система/виртуальная машина/кластер доступны?".

А если нам нужна доступность за отчётный период?

Сложности появляются уже на следующем шаге: как определить доступность системы на протяжении промежутка времени? Показатель очень важен для определения доступности различных компонент информационной системы и разработки мер по повышению этой доступности.

Например, как определить, насколько была доступна конкретная информационная система за последний месяц? Та же ситуация, если мы сформулируем данный вопрос к состоянию вообще любой конкретной услуги, например, насколько была доступна парикмахерская в соседнем подъезде за последний месяц?

Тут мы можем оперировать только долей, процентом доступности:

  • Парикмахерская была недоступна в один из дней, потому что парикмахеры объявили забастовку. Доступность – 96,67% за месяц наблюдений.

  • Виртуальная машина была недоступна 1 час по причине сбоя виртуального диска. Доступность – 99,86% за месяц.

Такое же определение было сформулировано ещё IBM для описания надёжности их мейнфреймов:

Availability means the probability that a system is operational at a given time, i. e. the amount of time a device is actually operating as the percentage of total time it should be operating.

Такой же подход используется публичными облачными провайдерами для подсчёта доступности конкретной виртуальной машины, кластера, или другого объекта:

Определение недоступности единичной виртуальной машины от Yandex:

Потеря внешней связности или загрузочного диска Виртуальной Машины. Соглашение об уровне обслуживания Сервиса не распространяется на случаи потери внешней связности, произошедшие вследствие наступления обстоятельств, независящих от Яндекса, в том числе, в случаях Dos или Ddos атак на Виртуальную машину Клиента.

Определение Google

"Monthly Uptime Percentage" means total number of minutes in a month, minus the number of minutes of Downtime suffered from all Downtime Periods in a month, divided by the total number of minutes in a month. Monthly Uptime Percentage is calculated per Network Service Tier and minutes will count towards each Network Service Tier separately if Network Service Tiers are changed during a calendar month.

Определение AWS:

For each individual Amazon EC2 instance (“Single EC2 Instance”), AWS will use commercially reasonable efforts to make the Single EC2 Instance available with an Instance-Level Uptime Percentage of at least 99.5%, in each case during any monthly billing cycle (the “Instance-Level SLA”). In the event any Single EC2 Instance does not meet the Instance-Level SLA, you will be eligible to receive a Service Credit as described below.

“Monthly Uptime Percentage” is calculated by subtracting from 100% the percentage of minutes during the month in which Amazon EC2 was in the state of Unavailability.

А если виртуальных машин много?

Самые жаркие дискуссии возникают именно на этом этапе, и всё дело в расхождении целей участников таких обсуждений:

  • Инженерам и менеджерам команд, которые потребляют услуги, нужно получить пул виртуальных машин, ни одна из которых никогда не будут отказывать, чтобы не просыпаться по ночам и достигать целевых показателей доступности информационных систем, работающих на этих виртуалках.

  • Инженерам и менеджерам инфраструктурных команд нужно получить реальные и достижимые показатели доступности инфраструктурных объектов. При этом способ достижения целевых показателей должен быть не фантастическим и умозрительным, а реализуемым на практике.

  • Топ-менеджерам нужна понятные метрики для оценки эффективности и надёжности инфраструктурного слоя и качества работы инфраструктурной команды.

Единственный путь, по которому можно прийти к общей позиции – пользователи должны принять, что сбои единичного элемента были, есть и будут, и свести их к нулю невозможно, а инфраструктурные команды могут и обязаны принимать системные меры, которые уменьшают количество и влияние этих сбоев.

Рассмотрим несколько вариантов подходов к подсчёту, которые мы обсуждали:

“Доступность – процент времени, когда все 100% объектов доступны”.

Для информационных систем или прикладного ПО этот же подход можно сформулировать таким образом: “Доступность – это количество дней, когда все 100% запросов к системе были корректно обработаны, поделённое на общее количество дней”.

Если мы принимаем такую формулу, то возникают такие интересные моменты:

  • Требования по доступности каждой конкретной виртуальной машины линейно растут с ростом инфраструктуры. Если у вас 100 виртуалок, и одна из них сломается на 30 минут, то доступность такой инфраструктуры составит 99,93%, что является нормальным показателем.

    Но! При этом, если у вас инфраструктура состоит 10 000 виртуалок и каждая из 100 сломается на 30 минут, то доступность составит всего 93%! При этом интенсивность отказов никак не менялась, оборудование работает с прежней надёжностью, исправление сбоев занимает всё те же 30 минут.

  • Из изложенного следует второй важный вывод – в любой крупной инфраструктуре всегда, или почти всегда, будут элементы, которые в данный конкретный момент времени недоступны. Одна виртуалка из 10-50 тысяч, один кластер Kubernetes из сотен и т. д. Доступность, посчитанная по такому принципу, никогда не поднимется выше 40-60%.

  • Фактически для команды инфраструктуры каждая новая виртуальная машина, кластер или другой объект – это снижение показателей команды без ухудшения качества реальной работы. Как бы вы ни старались работать лучше и качественнее, показатели будут неумолимо ползти вниз.

    Это ведёт к демотивации команды инфраструктуры – зачем работать качественно, если в целевые показатели всё равно не уложишься, как бы ты ни пытался.

“Доступность – процент времени, когда все критичные/продуктивные виртуальные машины доступны”.

Аналог для информационных систем или прикладного ПО: “Доступность – это доля дней, когда все запросы от VIP-клиентов были обработаны”

Такой подход обладает уже другими недостатками:

  • Как определить критичные и некритичные VM? Кто будет контролировать этот процесс, чтобы все 10 000 VM не были помечены как бизнес-крит? А если все, или почти все 10 000 VM в итоге помечены как бизнес-крит, то какой смысл в такой (довольно трудоёмкой) классификации? Откуда вообще берутся ненужные в рабочем процессе виртуалки и зачем их создавать в принципе?

  • Рассмотрим ситуацию, когда 15 дней из месяца все test- и dev- виртуалки были недоступны. При этом все prod-виртуалки продолжали корректно работать. Буквально стояла вся разработка нового функционала половину месяца. Однако, с точки зрения показателя доступности инфраструктуры по этому подходу – всё отлично, доступность 100%.

  • Самый важный вопрос – а может ли инфраструктурная команда как-то управлять доступностью какой-то конкретной виртуалки? На самом деле нет, это случайный процесс. Вышла из строя планка памяти, материнская плата или инженер задел соседний кабель при проведении работ – всё это случайные события, которые не поддаются контролю с точки зрения гарантированного предотвращения. Выходят из строя различные компоненты серверов, сетевой инфраструктуры и инженерной инфраструктуры ЦОДов и почти всегда это происходит непредсказуемо.

    Можно применять технологии, а-ля VMware Fault Tolerance / Site Recovery Manager, которые создают реплику виртуальной машины, но это уже попытка создать кластер средствами инфраструктуры, что уж точно тупиковый путь, который индустрия использует только для обеспечения доступности legacy-приложений, т. к. есть существенные ограничения таких технологий, которые я затрону чуть ниже.

Как же тогда считать доступность?

Попробуем рассмотреть несколько ситуаций:

  • Все 10 000 виртуальных машин доступны весь месяц, но в какой-то момент случился сетевой сбой и на 43 минуты все виртуальные машины были недоступны.

    Какова доступность в этом случае? Очевидно, что доступность сервиса виртуальных машин была:

Доступность=100\%-\frac{43м}{30д\cdot24ч\cdot60м}=99,9\%
  • Другая ситуация – в каждый момент времени 10 виртуальных машин из 10 000 недоступны. Какова доступность всех виртуальных машин?

Доступность=100\%-\frac{10}{10\:000}=99,9\%

И та, и другая ситуации – это доступность в 99,9%! Или, как мы ещё говорим, “три девятки”.

  • А теперь попробуем совместить рассуждения. Каков должен быть показатель доступности всей инфраструктуры в случае, если 50% (5 000) были недоступны 86 минут? А если 25% инфраструктуры недоступны 172 минуты?

    Кажется, что справедливый показатель доступности тот же самый – 99,9%.

В конечном счёте мы пришли к выводу, что время даунтайма части виртуальных машин необходимо нормировать на общее количество созданных виртуальных машин:

Доступность=100\%-\frac{Недоступные\:VM}{Всего\:VM}\cdot\frac{Время\:даунтайма}{Время\:в\:отчётном\:периоде}

Пример:

Одновременно вышли из строя 200 из 10 000 виртуальных машин, то есть в тот момент времени доступность составляет 98%. Продлилась недоступность 6 дней, или 1/5 месяца.

Целых 200 виртуалок “лежали” в течение 6 дней. Ужас или ужас-ужас-ужас? Как посмотреть, честно говоря!

Да, даунтайм составил 6 дней. Но дней в месяце 30, и в остальные 24 дня вообще была 100% доступность.

Да, 200 виртуалок были недоступны, но всего виртуалок 10 000 и остальные 9 800 виртуалок вообще не испытывали каких-либо проблем.

Среднемесячная доступность в нашем примере составит:

Доступность=100\%-\frac{200}{10\:000}\cdot\frac{6}{30} = 99,6\%

На графике доступности (ось X – дни, ось Y – доступные виртуалки) подобный сбой 200 виртуальных машин будет выглядеть вот таким образом:

График доступности
График доступности

Площадь голубого поля и есть наша недоступность. Здесь ось Y начинается с 9 700, поэтому цифра доступности в 99,6% кажется контринтуитивной и ложной. Вот так выглядит тот же график доступности, если ось количества виртуальных машин начать с нуля:

График доступности
График доступности

Глядя на такой график, уже гораздо проще согласиться с корректностью цифры 99,6%. Отношение площади зелёной зоны (достигнутая доступность в количестве виртуалок в каждый момент времени) к общей площади голубой и зелёной зон и есть наш показатель доступности.

Естественно, это вымышленный пример, в реальной жизни выходят из строя 2-3 виртуалки, за полчаса-час чинятся, через какое-то время выходят из строя ещё одна виртуалка и так далее. Задача инфраструктурной команды в этом случае – уменьшать системными мерами частоту сбоев и количество пострадавших виртуалок при сбое. Не предотвратить и свести к нулю, а уменьшить до достижимого предела.

Для нашего клиента, пользователя инфраструктуры, доступность, посчитанная по данной методике – это вероятность.

Вероятность того, что за прошедший период проверка доступности в случайный момент времени показывала положительный результат.

Вероятность получить ожидаемый результат в ходе однократной проверки. Проверяем доступность парикмахерской каждый день, получаем результат. Проверяем доступность виртуалки раз в минуту на протяжении месяца, получаем результат.

Такое определение доступности полностью соответствует определению доступности в терминах Reliability, availability and serviceability (RAS):

Availability means the probability that a system is operational at a given time, i. e. the amount of time a device is actually operating as the percentage of total time it should be operating.

Если нужно посчитать месячную доступность API для конечного пользователя, то точно по такой же формуле можем считать каждый день долю неуспешных запросов и нормировать на время. Хотя в случае с API численный показатель доступности можно посчитать и без учёта временного ряда. Однако, в случае с API полезна и форма кривой доступности, а не только абсолютный показатель – провал доступности до 0% в один из дней – не то же самое, что 96,7% каждый день.

Далее я расскажу, как можно использовать этот показатель для практического использования при проработке архитектуры приложения высокой доступности.

Как мне, пользователю, вообще воспринимать этот показатель доступности?

Иногда при этом добавляя: "Такой показатель невозможно использовать на практике!"

Сам термин “Доступность” (Availability) тесно связан с термином “Надёжность” (Reliability).

Ещё в 50-60-х годах прошлого века появилась теория надёжности для оценки влияния случайных сбоев на работоспособность технических систем. В теории надёжности термин коротко определяется так:

Надёжность — это вероятность безотказной работы.

По сути, доступность – это измеренная в цифрах фактическая, достигнутая надёжность системы.

Примечание: если говорить совсем корректно в терминах теории надёжности, то доступность следует воспринимать как коэффициент готовности.

Мы спроектировали систему с надёжностью 99,9%, проверили на различные сбои и подтвердили, что надёжность системы – 99,9%, то есть “три девятки”. Затем система была запущена в работу, наблюдаем её доступность в 99,99%, или “четыре девятки”, но надёжность системы всё ещё “три девятки”. И когда мы говорим, что инфраструктура, или информационная система, будет работать с доступностью ХХ% в месяц, то мы говорим именно о показателе надёжности. Чтобы не возникло путаницы, далее я буду продолжать использовать термин “Доступность”, но примеры буду приводить с использованием аппарата теории надёжности. Теория предоставляет хорошие инструменты для проектирования систем с заданным уровнем надёжности.

Как я уже описывал, сбой – случайное событие. Поэтому оценивать мы его можем только статистически. А принимаемые меры для повышения показателя доступности должны улучшать именно общую статистику сбоев и вести к снижению частоты возникновения сбоев и глубины аффекта от сбоя.

Этот показатель означает:

  • Для команды, использующей сервис – показатель целевой доступности любой виртуальной машины. Именно целевой показатель, а не гарантированный. Конкретная виртуалка может выйти за этот показатель, её доступность может быть и 100%, и 95%.

  • Для инфраструктурной команды – показатель, прямо отражающий бюджет ошибок. Процессы эксплуатации нужно выстроить так, чтобы сбои были с минимальным аффектом на пользователей, а также нужно научиться быстро устранять эти сбои. Естественно, первым делом нужно отладить процесс внесения изменений, чтобы они не генерировали рукотворные ошибки и не “съедали” бюджет ошибок.

Бред! Гиперскейлеры и публичные облака комитятся на доступность каждой виртуальной машины, значит, и от внутренней инфраструктурной команды мы можем требовать того же самого!

Безусловно, такая позиция имеет право на существование и давайте поговорим о деталях. Важна не только зона ответственности (каждая из виртуальных машин), но и мера этой самой ответственности (размер компенсации).

В случае с публичными облаками, если доступность единичной виртуальной машины выше 95-99%, то компенсация за простой от провайдера ограничена 10% от стоимости этой виртуальной машины. Повторю ссылки на SLA гиперскейлеров, где есть эти данные:

https://cloud.google.com/compute/sla

https://aws.amazon.com/ru/compute/sla/

https://yandex.ru/legal/cloud_sla_compute/

И при этом 99% доступности означает простой вплоть до 3 дней 15 часов в тот месяц, когда случился сбой. При стоимости виртуальной машины в пару тысяч рублей в месяц компенсация от провайдера публичного облака составит пару сотен рублей.

В то время, когда проводился анализ, наш целевой показатель доступности был 99,9%. Мы провели эксперимент и посчитали, какое количество виртуальных машин, за которые наша команда должна была бы выплатить компенсации в случае, если бы мы работали по модели публичного облака. Получилось четыре виртуальных машины. Из примерно 5-6 тысяч на тот момент. Такие затраты проще, эффективнее и дешевле заложить в финансовую модель тарифа, чем пытаться доводить количество сбоев до нуля.

Вряд ли будет адекватным требовать от внутренней инфраструктурной команды доступности всех виртуальных машин, если даже публичные облака-гиперскейлеры не готовы нести серьёзную финансовую ответственность за такую доступность, обладая существенно большими ресурсами и возможностями.

И как же тогда добиться целевого показателя доступности информационной системы?

Особенно остро вопрос доступности инфраструктуры стоит, если команде приложения ставится KPI по достижению доступности сервиса выше 99,9%, например, целевой показатель доступности какого-то портала – 99,99%.

Рефлекторное желание найти “серебряную пулю” в решении этого вопроса приводит менеджеров, ответственных за сервисы и прикладное ПО, в подразделение инфраструктуры с запросом на увеличение доли доступности каждой (а иногда и всех одновременно) из имеющихся виртуальных машин. Единственное, что могу посоветовать в такой ситуации – честно и настойчиво доносить информацию о том, что невозможно получить коммит по доступности конкретной виртуальной машины (или всех виртуалок какой-то информационной системы одновременно) в “пять девяток”, или 99,999%, как, бывало, у нас запрашивали. 

Невозможно из-за вполне объективных причин – как минимум, виртуальная машина работает на конкретном сервере в конкретном ЦОДе. ЦОДы Tier III обеспечивают гарантированный уровень доступности в 99,982% (годовой простой), а ЦОДы Tier IV – 99,995%. При этом в России я находил только один ЦОД с декларируемым уровнем Tier IV.

И каждому последующему уровню сложности на этой пирамиде нужен свой бюджет ошибок:

Инфраструктура по слоям абстракции
Инфраструктура по слоям абстракции

Очевидно, что невозможно обеспечить доступность конкретной виртуальной машины даже в 99,99%, не говоря уже о пяти девятках. Выход, конечно, в кластеризации и дублировании точек отказа, но это не единственное, что придётся сделать.

На кластеризации остановлюсь чуть подробнее, потому что есть, условно, два способа – кластеризация на уровне инфраструктуры и кластеризация на уровне приложения.

Кластеризация инфраструктуры – когда дублируются виртуальные машины, виртуальные диски и даже, иногда, состояние оперативной памяти. Проблем тут несколько: при сбое виртуальная машина испытывает hard reset и не факт, что не “посыпется” файловая система; приложение должно автоматически запускаться при перезагрузке и быть готовым к работе; виртуальная машина не может быть очень “тяжёлой”, не может иметь большое количество CPU/RAM/Disk; нужна большая пропускная способность сети в точку, куда машина реплицируется, т. к. приходится передавать данные об изменениях блочного устройства (диска), которые заведомо больше, чем объём изменившихся данных приложения.

Кластеризация на уровне приложения лишена этих ограничений и имеет только один минус – она более трудоёмкая для команды разработки и сложная для реализации на стороне приложения. При этом в обоих случаях нужно дублировать и резервировать ресурсы для виртуальной машины – чудес не бывает и этого не избежать. Существует множество реализаций такой концепции, создано много инструментов, упрощающих жизнь – от Keepalived и Rsync до Kubernetes и распределённых файловых систем.

Всё описанное делает реализацию кластеризации на уровне ПО в конечном счёте дешевле, чем пытаться создавать кластеры на уровне инфраструктуры, как это пытались делать в нулевых  годах.

Разбираемся с вероятностями отказов

Хорошо, кажется, что мы разобрались с тем, что нельзя полагаться на то, что сбоев не будет совсем и нужно к сбоям готовиться заранее. Перед тем, как определяться с тем, что делать дальше, давайте чуть погрузимся в то, как доступность инфраструктуры сказывается на доступности информационной системы. И попробуем посчитать достижимую доступность на примере информационной системы, состоящей из 10 компонент, размещённых на отдельных виртуальных машинах с доступностью 99,9% каждая. При этом отказ любого из компонент приводит к недоступности информационной системы целиком – у нас есть 10 точек отказа.

Всего рассмотрим три варианта:

  1. без дублирования точек отказа;

  2. дублирование каждой из точек отказа;

  3. дублирование приложения целиком.

Вариант 1 – без дублирования точек отказа

Необходимо предполагать, что каждая из виртуальных машин может иметь простой до 43 минут 48 секунд в месяц, и это штатное поведение инфраструктуры. Сбои на временной шкале разложатся как-то так:

VM1 выходит из строя во второй день месяца на 44 минуты, VM2 – в четвёртый день и т. д.
VM1 выходит из строя во второй день месяца на 44 минуты, VM2 – в четвёртый день и т. д.

Суммарное время недоступности за месяц составит 7 ч 18 мин, или, если учесть вероятность пересечения сбоев, то 7 ч 12 мин. Доступность системы составит 99% при доступности инфраструктуры в 99,9%.

В итоге за счёт наличия в системе 10 точек отказа мы теряем одну “девятку” доступности!

Для рассматриваемой ситуации математика очень проста и выглядит так:

Вероятность\:отказа\:ИС=Вероятность\:отказа\:VM1+...+Вероятность\:отказа\:VM10==\frac{1}{1000}+\frac{1}{1000}+...+\frac{1}{1000}=10\cdot\frac{1}{1000}=\frac{10}{1000}=\frac{1}{100}

Вариант 2 – дублирование каждой из точек отказа

Теперь посмотрим, как повлияет кластеризация компонент, которые являются точками отказа для информационной системы. На временной шкале такие сбои будут выглядеть так:

На рисунке компонент HA1 деградирует из строя во второй и 12-й день месяца на 44 минуты, VM2 – в четвёртый и 21-й день и т. д.
На рисунке компонент HA1 деградирует из строя во второй и 12-й день месяца на 44 минуты, VM2 – в четвёртый и 21-й день и т. д.

На этом рисунке клеточки обозначены жёлтым цветом, потому что не происходит отказа ИС, в этот день компонент работает “на одной ноге”, т. к. дублирующий компонент вышел из строя.

В случае, если мы кластеризуем (и обеспечим автоматическое переключение на резерв при сбое) каждый такой компонент, то отказ информационной системы будет наступать только в том случае, когда выйдет из строя и основной экземпляр компонента, и резервный. Отказы должны случиться одновременно, такая вероятность вычисляется умножением вероятностей отказа каждого из компонент.

Вероятность\:отказа\:ИС=\frac{1}{1\:000}\cdot\frac{1}{1\:000}+\frac{1}{1\:000}\cdot\frac{1}{1\:000}+...+\frac{1}{1\:000}\cdot\frac{1}{1\:000}==10\cdot(\frac{1}{1\:000}\cdot\frac{1}{1\:000})=\frac{1}{1\:000\:000}=\frac{1}{100\:000}

Потенциальная доступность такой системы составит 99,999% при доступности инфраструктуры в 99,9%.

В таком варианте обеспечения надёжности можно получить наиболее устойчивый сервис – мы к доступности инфраструктурного слоя добавляем сразу “две девятки”. Правда, подойдёт он не для всех – как правило, потребуется плоская сеть между ЦОДами для репликации данных каждого компонента. Плюс потребуется организовать автоматическое переключение на резерв для каждого компонента. Но в своей практике я встречал такие реализации, так тоже делают.

Вариант 3 – дублирование всего приложения целиком

В этом варианте мы не дублируем каждый критичный компонент, а резервируем приложение целиком, делаем его копию на другой площадке и обеспечиваем автоматическое переключение на резерв в случае любого сбоя основной копии.

В таком варианте вероятность сбоя для одной из копий приложения будет такая же, как в первом варианте – 1/100. При этом для отказа сервиса целиком нужно, чтобы одновременно отказали обе копии.

Вероятность\:отказа\:ИС=\frac{1}{100}\cdot\frac{1}{100}=\frac{1}{1\:000}

Потенциальная доступность такой системы составит 99,99% при доступности инфраструктуры в 99,9%.

Такой вариант организовать чуть проще, он подходит для любой среды, не требуется плоская сеть и механизм переключения на резерв требуется не для каждого компонента, а для приложения целиком. В случае необходимости можно и третью копию приложения с кворумом организовать для большей надёжности.

11 принципов системы высокой доступности

Рассмотрим также другой аспект обеспечения высокой доступности приложения. Исключительно важно посмотреть на ещё один параметр, о котором забывают, когда речь идёт о заведомых “магических девятках” – о бюджете ошибок. Давайте посмотрим, каков размер бюджета ошибок для разных уровней доступности:

Бюджет ошибок
Бюджет ошибок

Почему важно смотреть на целевую доступность с точки зрения бюджета ошибок? Потому что это ваш инструмент при переговорах с бизнесом. Когда мы говорим о задаче “поднять уровень доступности сервиса с трёх девяток до четырёх девяток”, то возникает когнитивное искажение, что команде сервиса нужно улучшить свою работу всего лишь на 33%. Глядя на бюджет ошибок, сразу становится очевидно, что работу придётся улучшать на порядок – в 10 раз!

Ещё раз: это очень важно – не на 33%, а в 10 раз, или на 1 000%!

Такое движение вперёд невозможно обеспечить каким-то одним простым решением, это всегда изменение подходов по решению задачи. Давайте рассмотрим пример: допустим, нам поступила задача обеспечить доступность сервиса на уровне “четыре девятки” при имеющейся доступности в “три девятки”. Что это значит для нас:

  1. Допустимый месячный простой падает с почти 44 минут до 4,5 минут. Допустим, у нас есть текущая статистика отказов, и мы понимаем, что можем рассчитывать на показатель “не более одного сбоя за год”, и смогли договориться с бизнесом вести подсчёт на годовом промежутке. Но и за год мы можем “лежать” не более 52 минут. 

    При годовом бюджете ошибок в почти 9 часов мы можем позволить себе не иметь дежурную смену, которая досконально знает сервис – всегда можно поднять ночью разработчика и инженера и, в итоге, починить сервис. Даже если сотрудники в отпусках и больничных – у нас есть время на сбор пожарной команды, диагностику и устранение неполадки.

    При годовом бюджете в 52,5 минуты у нас такой опции нет! Более того, нет времени даже на диагностику – необходимо моментально починить сервис.

  2. Из предыдущего пункта вытекает ещё один момент – так как нет времени на диагностику, то мы должны всегда иметь наготове копию информационной системы, должны иметь “горячий резерв”. Причём, вспоминая об уровне доступности ЦОДа Teir III (99,982%), мы должны иметь горячий резерв на другой площадке, в другом ЦОДе.

    Нет времени на восстановление из резервной копии, нет времени на повторный ручной деплой отказавшего компонента, нет времени на автоматизированный деплой всего приложения целиком CI/CD-пайплайном.

  3. Сверхвысокую важность приобретает мониторинг сервиса. Нужно научиться ловить ошибки ещё до момента, когда сбой заафектит пользователей и скажется на доступности сервиса. Если мониторинг показывает только наличие неполадки, но не стреляет алармами за сутки-двое до сбоя – его надо переделать.

Список можно продолжать, и именно такие моменты я и имею в виду, когда говорю, что для роста всего лишь на одну “девятку”, придётся переделать почти всё, придётся изменить подходы к обеспечению заданной доступности – это всегда качественный рост.

При заданной доступности в “две девятки” можно даже не иметь запасного оборудования – есть время купить необходимое или дождаться гарантийной замены. При заданной доступности в “три девятки” оборудование уже должно быть в наличии на площадке, но пожарная команда может собираться при сбое по звонку. Для уровня доступности в “четыре девятки” нужен горячий резерв и автоматическое переключение на резерв в случае сбоя.

В ходе обсуждений мы сформулировали несколько принципов для команды высокодоступной информационной системы:

Технический блок:

  1. Плотно проработать дублирование компонент, которые являются точками отказа для ИС. Встроить обработку ошибок в такие компоненты.

  2. Поддерживать актуальную архитектуру с указанием адресов/имён инфраструктурных компонент.

    Критически важно для быстрой диагностики сбоя информационной системы кросс-функциональной аварийной командой.

  3. Иметь выстроенный и работоспособный CI/CD-пайплайн для повторного деплоя ПО вместе с инфраструктурой.

    Часто быстрее не дебажить и восстанавливать компонент, а переразвернуть его пайплайном. Кроме того, дебаг и восстановление можно проводить параллельно с раскаткой пайплайна, чтобы минимизировать простой.

  4. Организовать полный мониторинг, логирование и трейсинг самой информационной системы, инфраструктурных метрик, бизнес-метрик и метрик доступности других сервисов, от которых зависит ваше приложение.

    Ускорит поиск причины сбоя, поможет при root cause анализе для недопущения повторения сбоя по той же причине.

  5. Настроить и периодически тестировать резервные копии компонент, которые хранят внутри себя состояние (state): базы данных, файловые хранилища.

    Такие компоненты недостаточно переразвернуть CI/CD-пайплайном, необходимо восстанавливать состояние из резервной копии.

  6. Иметь тестовую среду (архитектурно повторяющую продуктив) и автоматизированные (желательно), либо ручные тесты: интеграционные, нагрузочные, а также тесты отказоустойчивости и восстановления из резервной копии.

    Регулярно проводить такие тесты.

Организационный блок:

  1. Иметь выстроенный процесс разработки и тестирования по схеме dev-test-prod.

    Иначе сбои при релизах будут уменьшать доступный бюджет ошибок (и без того малый!).

  2. Регламенты, инструкции и работающие процессы по Fault (Postmortems, Incident Management, HA/DR Plan), Change (Change Management & Updates) и Performance (Metrics Tracking & Scaling).

    Система может остановиться не только при сбое, но и при росте, когда usage какого-то компонента, за которым никто не следит, подойдёт к внутреннему лимиту производительности.

  3. Работающие процессы поддержки L1 / L2 / L3 по функционированию самого приложения. Чтобы не заниматься судорожным ночным поиском инженера, который запускал приложение год назад, а сейчас вообще уже уволился.

  4. Отдельным пунктом – учёт требований доступности при реализации изменений. Приоритизация Feature Requests по высокой доступности для Business Critical и Mission Critical систем.

  5. Соответствие информационной системы требованиям ИБ и высокий уровень коммуникаций с ИБ.

    Никому не нужно, чтобы бизнес-критичный сервис остановил хакер или сама ИБ, заблокировав сетевое взаимодействие одним из своих инструментов.

Применяя даже часть из этих принципов, можно значительно повысить доступность критичного сервиса и добиться его устойчивой работы. Мы активно используем эти принципы в нашем частном облаке Х5 и гарантируем для наших пользователей показатель доступности в 99,95%, а фактическая доступность сервисов облака за последние полгода находится в районе 99,99%.


Надеюсь, статья будет интересна. Уверен, что какие-то части этого описания очевидны читающим, либо встречались ранее на практике. Другие же принимают, возможно, ошибочные решения в силу правильной привычки искать наиболее простые пути по решению возникающих проблем. К сожалению, иногда самый простой и очевидный метод не ведёт к результату. Я постарался агрегировать и описать имеющиеся подходы и выстроить логику, которую можно использовать при принятии тех или иных решений по обеспечению доступности критичных сервисов. Буду рад комментариям и любой обратной связи!

Комментарии (3)


  1. itGuevara
    29.08.2024 18:53

    Примечание: если говорить совсем корректно в терминах теории надёжности, то доступность следует воспринимать как коэффициент готовности.

    Точнее так:

    Кг - это вероятность застать систему в работоспособном состоянии (ничего не отвалилось), а коэф. доступности - вероятность застать систему в свободном состоянии, т.е. готовой принять \ обработать нагрузку (не занята).

    К расчету надежности дублированной группы. Отказоустойчивые конфигурации (резервирование) – сложная штука и нормальный расчет коэффициента готовности реального отказоустойчивого сервера (например, реального кластера) еще не встречал (у кого есть – покажите). Там должен быть как минимум параметр «вероятность отказа, не обнаруженного внутренней системой контроля», т.к. идеальных систем нет. Состояние необнаруженного отказа - это например, когда узел поломан (не обрабатывает нагрузку), но keep-alive "исправлено" шлет остальным узлам (или резервные узлы не переключаются при отсутствии на входе сигнала "пока жив" от соседа). Даже один не обнаруженный из пятисот обнаруженных отказов изменит характер зависимости.

    Считать Кг реальной системы нужно марковскими цепями (граф состояний, отражающих резервирование, и далее решение системы уравнений), т.к. последовательно-параллельные статические схемы не передадут даже качественно модель отказов системы с резервом.

    Есть какие-либо показатели и расчеты (примеры) Business continuity & Operational resilience?


    1. moskvalex Автор
      29.08.2024 18:53

      Запихнуть в одну, даже очень длинную, статью весь учебник по теории надёжности - задача такой же достижимости, как и задача получения виртуалки с доступностью 100%, я не ставил себе такой цели :)

      Цель - дать всем общее представление, коллегам-инфраструктурщикам - аргументы в переговорах, а коллегам-менеджерам - понимание, где искать заветные "девятки" доступности.


      1. itGuevara
        29.08.2024 18:53

        Мой комент выше - запрос на уточнение. А дать уточнение в коменте, в личке или отдельной статьей - это уже Ваш выбор.