Когда вы запускаете приложение в облаке, рано или поздно что-нибудь сломается. Это не пессимизм, а закон больших чисел: серверов много, и какой-то из них обязательно выйдет из строя. В AWS ломаются отдельные виртуальные машины (их называют instances), иногда целые датацентры (зоны доступности), очень редко — регионы целиком. Отказоустойчивость (resilience) — это не про то, чтобы ничего не ломалось, а про то, чтобы вы заранее знали, что произойдёт, когда сломается, и чтобы пользователь этого почти не заметил.

Главная идея простая: решение «что делать при отказе» принимается заранее, на бумаге и в архитектуре, а не в панике в три часа ночи во время инцидента. Disaster recovery (DR, аварийное восстановление) — это ваш план на случай, когда обычной защиты не хватило и нужно восстанавливать систему. В этой статье разберём базовые понятия по шагам: где размещать копии, как измерять требования к восстановлению и какие бывают стратегии.

активный-активный две полные копии: секунды, 100 % и больше тёплый резерв уменьшенная живая копия: минуты дежурная лампочка реплика базы живёт, остальное поднимают: десятки минут копии и восстановление RPO и RTO часы, 5–10 % цены

Снизу вверх растут цена и скорость восстановления. Бизнес называет допустимые RPO и RTO, и берут первую снизу стратегию, которая в них укладывается: «активный-активный на всякий случай» это сожжённый бюджет.

Обязательно

Зоны доступности и регионы

Сначала про географию AWS, без неё дальше не разобраться.

  • Регион (region) — большая географическая область, например Франкфурт или Северная Вирджиния. Внутри региона ваши данные не покидают его пределов.
  • Зона доступности (Availability Zone, AZ) — отдельный физический датацентр (или группа близких датацентров) внутри региона. В каждом регионе их обычно три и больше. Зоны соединены быстрыми каналами, но физически разнесены: пожар или сбой питания в одной зоне не задевает другие.

Аналогия: регион — это город, а зоны доступности — разные здания в этом городе. Если в одном здании отключилось электричество, работа продолжается в соседнем.

Multi-AZ против multi-region

Есть два уровня защиты, и они стоят очень по-разному.

Multi-AZ — это когда ваши ресурсы продублированы в нескольких зонах доступности одного региона. Защищает от отказа целой зоны (того самого «здания»). Это дёшево, задержка между зонами крошечная, и в большинстве сервисов AWS такая защита встраивается почти автоматически. Например, группа автомасштабирования (Auto Scaling Group) раскидывает серверы по разным зонам, а у базы данных RDS есть режим Multi-AZ, который держит горячую копию в другой зоне. Переключение на неё занимает обычно минуту-две, и приложение обязано переподключиться — вот это, а не ноль, и есть ваш RTO для такого отказа. Подробнее про эту базовую защиту — в статье про масштабирование и доступность. Multi-AZ делают практически всегда — это разумный минимум.

Multi-region — это полная копия системы в другом регионе (другом «городе»). Защищает от отказа целого региона. Такое случается очень редко, но если случается — это катастрофа. Расплата за защиту высокая: данные нужно реплицировать через сотни и тысячи километров, следить за их согласованностью и уметь переключать трафик между регионами. Чем это делают на практике: базу — Aurora Global Database или глобальными таблицами DynamoDB, файлы — межрегиональной репликацией объектного хранилища, а переключение трафика — через Route 53 с проверками здоровья, чтобы записи DNS сами увели пользователей в живой регион. Это делают только для по-настоящему критичных систем, где недоступность региона недопустима — например, в финансах.

Простое правило: multi-AZ — почти всем, multi-region — только когда требования к доступности это реально оправдывают, потому что стоимость и сложность вырастают резко.

Ещё один важный нюанс: multi-AZ и multi-region решают разные проблемы и не взаимозаменяемы. Multi-AZ спасает от технического сбоя оборудования. Multi-region вдобавок спасает от региональной катастрофы. Но ни то, ни другое не спасает от логической ошибки — если вы случайно удалили таблицу или выкатили багованный код, копия в другой зоне или регионе аккуратно повторит за вами и удаление, и баг. От таких ситуаций защищают только бэкапы, о которых ниже.

RPO и RTO

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

  • RPO (Recovery Point Objective) — сколько данных вы готовы потерять, измеряется во времени. RPO = 5 минут означает: «если случится катастрофа, мы согласны потерять последние 5 минут данных, не больше». Эта метрика определяет, как часто делать бэкапы и репликацию. Хотите RPO поменьше — копируйте данные чаще.
  • RTO (Recovery Time Objective) — за какое время система должна снова заработать. RTO = 1 час означает: «через час после аварии сервис снова доступен». Эта метрика определяет, какую стратегию восстановления выбрать.

Аналогия для RPO и RTO: представьте, что вы пишете документ. RPO — как часто вы нажимаете «Сохранить» (сколько работы потеряете при сбое). RTO — как быстро вы откроете компьютер заново и продолжите работать после того, как он завис.

Чем меньше оба числа, тем дороже решение. Важный момент: RPO и RTO задаёт бизнес, а не инженер. Бизнес решает, во что обходится час простоя и потеря данных, а инженер уже подбирает под эти цифры подходящую архитектуру.

Маленький пример. Интернет-магазин говорит: «терять заказы нельзя совсем, но магазин может полежать полчаса без катастрофы». Это значит RPO близок к нулю (данные дублируем непрерывно), а RTO порядка тридцати минут (восстановиться можно не мгновенно). Другой случай — внутренний отчётный сервис: «потерять данные за сутки не страшно, но к утру всё должно работать». Тут RPO в сутки и RTO в несколько часов — и решение будет в разы дешевле. Одни и те же технологии, но разные цифры дают совершенно разную архитектуру и стоимость.

Четыре стратегии аварийного восстановления

AWS выделяет четыре основные стратегии DR. Они выстроены по возрастанию: чем выше в списке, тем дешевле и тем медленнее восстановление; чем ниже — тем дороже и быстрее.

  1. Backup & restore (бэкап и восстановление) — вы только храните резервные копии. Случилась катастрофа — разворачиваете инфраструктуру заново и заливаете данные из бэкапа. Самый дешёвый вариант, но RTO и RPO большие (часы). Подходит для систем, которые могут позволить себе подождать.

  2. Pilot light («дежурная лампочка») — постоянно работает только самое ядро, обычно реплика базы данных, которая всё время получает свежие данные. Остальное (серверы приложения, балансировщики) выключено и поднимается только при аварии. Название — отсылка к маленькому огоньку в газовой колонке, от которого мгновенно зажигается основное пламя. RTO заметно меньше, цена умеренная. Одна честная оговорка: реплика в другой регион работает асинхронно, поэтому при внезапном отказе региона последние секунды записей всё-таки можно потерять. Строгий нулевой RPO через pilot light не получается — это стоит проговорить до того, как бизнесу пообещали «не потеряем ничего».

  3. Warm standby («тёплый резерв») — в запасном регионе работает уменьшенная, но полностью живая копия всей системы. Она реально обслуживает что-то (или просто готова), а при аварии масштабируется до полного размера и принимает весь трафик. RTO маленький, но и платить приходится постоянно за работающую копию.

  4. Multi-site active-active («активный-активный») — полноценные копии системы работают одновременно в нескольких регионах и обе обслуживают пользователей. Если один регион падает, трафик просто идёт во второй, почти без паузы. RTO близок к нулю, но это самый дорогой и сложный вариант: нужно синхронизировать данные между регионами в обе стороны.

Порядки величин по четырём стратегиям — чтобы сопоставлять их с требованиями, а не со словами «дешевле» и «быстрее». Числа ориентировочные, для сервиса средней величины:

СтратегияRPORTOОтносительная цена
Бэкап и восстановлениечасы (частота копий)часы, иногда сутки5–10 % от основного контура (только хранение копий)
Дежурная лампочкаминуты (асинхронная репликация)десятки минут15–25 % (реплика базы плюс образы)
Тёплый резервсекунды-минутыминуты30–60 % (уменьшенная, но живая копия)
Активный-активныйблизок к нулюсекунды100 % и больше (две полные копии плюс сложность)

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

Чтобы было нагляднее, представьте резервный автомобиль на случай поломки основного. Backup & restore — это запчасти в гараже: дёшево, но собирать машину придётся долго. Pilot light — машина без колёс, колёса докупаются при поломке. Warm standby — заведённая, но стоящая в гараже малолитражка, на которую можно быстро пересесть. Active-active — две одинаковые машины едут параллельно, и если одна заглохла, вы просто продолжаете во второй.

Выбор стратегии — это компромисс между требованиями (RPO/RTO) и бюджетом. Частая дорогая ошибка — строить active-active там, где задачам с запасом хватило бы pilot light.

Доступность и восстановление: это разные процессы

RPO и RTO описывают, чего вы хотите. Не менее важно, кто и как это делает — и здесь разница между высокой доступностью и аварийным восстановлением принципиальная, хотя по определению они похожи.

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

Восстановление в другом регионе почти всегда запускает человек. И это не недоработка, а осознанный выбор, у которого есть причины:

  • Отказ региона трудно отличить от частичного сбоя. Половина сервисов отвечает, половина нет; проблема может быть у вас, а может у провайдера, и может пройти сама через десять минут. Автоматика в такой ситуации ошибается в обе стороны.
  • Переключение регионов — это, как правило, переключение записи. База в резервном регионе была репликой; сделать её основной — операция односторонняя, и обратно так просто не вернуться. Автоматически запускать необратимое решение на основании неоднозначного признака — плохая идея.
  • Расхождение данных. Репликация между регионами асинхронна: в момент переключения последние секунды записей могут быть потеряны, а если после этого основной регион оживёт, в нём окажутся данные, которых нет в резервном. Кто-то должен решить, что с ними делать.
  • Цена ошибки. Ложное переключение обходится дороже, чем несколько минут простоя.

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

  1. Кто объявляет аварию. Один человек с явной ролью (дежурный, руководитель дежурства) и понятный критерий: что должно быть верно, чтобы объявить. Например: «ошибки выше 50 % дольше десяти минут и статус провайдера подтверждает сбой региона».
  2. Кто нажимает переключение и по какому документу. Документ — это последовательность команд или один готовый сценарий; в момент аварии его не пишут, а выполняют.
  3. Как оповещают пользователей и соседние команды.
  4. Как проверяют, что переключение удалось: конкретные проверки, а не «вроде работает».
  5. Кто решает вопрос о возврате и когда.

Автоматическое переключение между регионами всё-таки встречается, и почти всегда — на уровне трафика, а не данных: проверки работоспособности в службе доменных имён переводят пользователей на живой регион, а база и там и там доступна для записи (активный-активный). То есть автоматика возможна, когда стратегия дороже; в остальных случаях переключает человек.

Бэкапы и их проверка

Бэкап, который ни разу не восстанавливали, — это не бэкап, а надежда. Самый частый провал в DR звучит так: «бэкапы вроде были, а восстановиться не смогли» — файл оказался битым, не хватило прав, скрипт устарел или процесс занял в десять раз больше времени, чем рассчитывали.

Поэтому хорошая практика складывается из двух частей. Первая — регулярные автоматические бэкапы: с частотой, которая укладывается в ваш RPO, и со сроком хранения, который вам нужен. Цифры, от которых считают RPO, стоит знать заранее: автоматические копии RDS хранятся по умолчанию неделю, если базу создавали в консоли (через командную строку — сутки), максимум — 35 дней, и восстановиться внутри этого срока можно на любую секунду.

И ещё одно свойство, которое отличает бэкап от реплики: копия должна лежать там, где её не достанет та же учётная запись, из-под которой удалили данные, — в отдельном аккаунте, в хранилище с запретом на удаление. Иначе злоумышленник (или неудачно запущенный скрипт) снесёт одним движением и данные, и все копии. AWS Backup умеет настраивать такие политики централизованно. Вот как выглядит запуск разовой резервной копии через командную строку (AWS CLI):

aws backup start-backup-job \
  --backup-vault-name production-vault \
  --resource-arn arn:aws:rds:eu-central-1:111122223333:db:orders-db \
  --iam-role-arn arn:aws:iam::111122223333:role/AWSBackupDefaultServiceRole

Вторая, не менее важная часть — учения по восстановлению. Периодически нужно реально поднимать систему из бэкапа в изолированной среде и проверять две вещи: что данные целы и что вы укладываетесь в свой RTO. Только пройденное «учение» превращает бэкап из строчки в отчёте в настоящую страховку.

Где это применяется

Отказоустойчивость и DR — это не отдельная экзотическая тема, а часть определения «готового к продакшену» сервиса наравне с масштабированием и наблюдаемостью. Когда архитектуру согласуют с заказчиком, первым делом просят ответить, что будет при отказе зоны или региона и как система восстановится, — и честный ответ опирается ровно на эти понятия: multi-AZ как база, multi-region по необходимости, стратегия DR под заданные RPO/RTO и проверенные бэкапы. Надёжность (reliability) — один из столпов методики проектирования Well-Architected, так что понимать DR полезно при любой работе с облаком.

Типичные ошибки новичков:

  • Считать, что AWS «и так всё сохранит». Облако даёт инструменты, но политику бэкапов и стратегию DR настраиваете вы. По умолчанию никто за вас данные на случай катастрофы не дублирует.
  • Путать высокую доступность и аварийное восстановление. Multi-AZ держит сервис живым при мелких сбоях, но это не замена бэкапам: если кто-то по ошибке удалил данные, реплика в другой зоне честно повторит это удаление.
  • Строить самый дорогой вариант «на всякий случай». Active-active без реального требования к нулевому RTO — это сожжённый бюджет. Сначала RPO/RTO от бизнеса, потом стратегия. Тему денег стоит изучить отдельно — см. оптимизацию затрат.
  • Ни разу не проверять бэкап. Самая обидная ошибка: план есть, копии есть, а в момент аварии всё рассыпается.
Дополнительно: при первом чтении можно пропустить

Глубже: возврат: половина процедуры, о которой не думаютрасширенное

Переключились в резервный регион — это половина истории. Вторая половина, обратное переключение, обычно не описана вовсе, и именно на ней застревают надолго.

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

Как возвращаются, по шагам.

  1. Убедиться, что основной регион здоров — не «доступен», а именно здоров: сервисы, база, сеть, квоты.
  2. Развернуть репликацию в обратную сторону. Теперь резервный регион — источник правды, а основной должен догнать его. Это отдельная работа: для управляемых баз обычно означает поднять в основном регионе реплику от текущего основного экземпляра.
  3. Дождаться, пока отставание станет близко к нулю. Это может занять часы, если данных много.
  4. Выбрать окно. Обратное переключение делают в спокойное время и с коротким запретом записи (несколько минут), чтобы не потерять последние транзакции. Это и есть ключевое отличие от аварийного переключения: возврат — плановая операция, и его можно сделать аккуратно.
  5. Переключить трафик и убедиться, после чего вернуть репликацию в обычное направление.

Что делать со старым состоянием основного региона. Его не «сливают» с новым — почти всегда прежние данные объявляются устаревшими и перезаписываются из резервного региона. Попытка объединить две разошедшиеся копии вручную — источник самых неприятных ошибок в данных, и её стоит избегать любой ценой. Если объединение всё-таки необходимо (например, в основном регионе остались платежи, которых нет в резервном), это отдельная задача сверки, которую делают по журналу операций, а не копированием таблиц.

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

Глубже: учения: намеренно уронить самимрасширенное

«Периодически поднимать систему из копии» — верно, и есть инструменты, которые позволяют проверять не только копии, но и поведение при отказе.

Fault Injection Service — сервис AWS для управляемых экспериментов: он умеет по сценарию гасить экземпляры, отключать зону доступности для группы масштабирования, добавлять задержку и потери в сеть, вызывать переключение управляемой базы, отбирать процессор и память у машины. Ценность в двух вещах: у эксперимента есть условия остановки (при превышении порога ошибок он сам всё откатывает) и он описывается как объект, то есть повторяем и версионируем.

aws fis start-experiment --experiment-template-id EXT123abc

Что проверяют в первую очередь, по возрастанию смелости:

  1. Отказ одного экземпляра. Проверка, что группа масштабирования заменяет копию, а пользователи этого не видят. Самое дешёвое и самое полезное первое учение.
  2. Переключение управляемой базы. У этого есть штатная кнопка (принудительное переключение), и проверяет она главное: переподключается ли приложение и сколько это занимает.
  3. Отказ зоны доступности. Сложнее: имитируют отключением подсети или гашением всех копий в зоне. Здесь обычно и выясняется, что что-то было развёрнуто в одной зоне.
  4. Отказ зависимости. Задержка или отказ при обращении к соседнему сервису и к внешнему API — проверка таймаутов, повторов и предохранителей.
  5. Отказ региона — самое дорогое учение; чаще проводят «настольную» версию (разбор по шагам без реального переключения) плюс проверку отдельных элементов процедуры.

Как проводят, чтобы это было безопасно. Сначала на стенде, потом в боевом контуре в согласованное окно. Заранее: гипотеза («сервис продолжит отвечать с ростом задержки не больше чем на 20 %»), условия остановки, дежурный на связи и способ всё вернуть. После — короткий отчёт: что сломалось не так, как ожидали, и какие правки из этого следуют. Именно эти правки и есть результат учения, а не сам факт его проведения.

Глубже: что мешает подняться в резервном регионерасширенное

Отдельный список проблем, которые обнаруживаются в самый неподходящий момент, потому что в обычной работе их не видно.

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

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

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

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

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

Службы доменных имён и сертификаты. Переключение трафика делается записями DNS, и здесь работает время жизни записи: значение в час означает, что часть пользователей будет идти в мёртвый регион ещё час. Для сервисов, где важен быстрый переход, время жизни заранее ставят коротким (30–60 секунд). Сертификаты для резервного региона выписывают заранее — в момент аварии их выпуск и проверка домена превращаются в лишние часы.

Люди и доступы. У дежурного должны быть права на переключение в резервном регионе и работающий доступ, когда основной контур недоступен (в том числе если ваш вход зависит от системы, которая живёт в упавшем регионе). Это проверяется на учениях и почти всегда обнаруживается там впервые.

Коротко

  • Multi-AZ дублирует ресурсы по зонам одного региона и стоит дёшево, multi-region это полная копия в другом регионе и стоит дорого; ни то, ни другое не спасает от ошибочного удаления, которое реплика честно повторит.
  • RPO это сколько данных можно потерять, RTO за сколько сервис обязан подняться; оба числа называет бизнес, а инженер подбирает под них архитектуру.
  • Четыре стратегии по возрастанию цены: копии и восстановление за часы, дежурная лампочка с живой репликой базы, тёплый резерв уменьшенной копией, активный-активный за две полные копии; берут первую сверху, которая укладывается в RPO и RTO.
  • Доступность внутри региона происходит сама, восстановление в другом регионе запускает человек по заранее написанной процедуре: кто объявляет аварию, кто нажимает, как оповещают и проверяют.
  • Возврат это вторая половина процедуры: основной регион догоняет резервный обратной репликацией, переключаются в спокойное окно с коротким запретом записи, старое состояние перезаписывают, а не сливают.
  • Учения проводят по возрастанию смелости: отказ экземпляра, принудительное переключение базы, отказ зоны, отказ зависимости, настольный разбор отказа региона; Fault Injection Service делает это по сценарию.
  • В резервном регионе ломаются порядок подъёма, квоты по умолчанию, образы в реестре упавшего региона, ключи шифрования и секреты, которые не пересекают границу, внешние системы со списками адресов, TTL записей DNS и права дежурного.
  • Копия, которую ни разу не восстанавливали, это надежда: копии снимают с частотой под RPO, хранят там, где их не достанет та же учётная запись, и регулярно поднимают из них систему в изолированной среде.

Что почитать дальше