«А что будет, когда это сломается?» — вопрос, который отличает боевую систему от учебной. Сломается обязательно: упадёт узел, выйдет из строя зона, кто-то удалит не ту таблицу. Разница между катастрофой и штатной ситуацией — в том, подготовились ли вы заранее. Разберём два уровня подготовки. Оба стоят на нескольких зонах, поэтому начните с масштабирования и доступности, если ещё не читали.
Три разных отказа и три разных ответа: от дата-центра спасают копии по зонам, от медленного соседа таймауты, предохранитель и деградация, а от ошибочного удаления только копии, отдельные от боевых данных, которые реплика повторит.
Отказоустойчивость против аварийного восстановления
Это два разных уровня, их полезно различать.
- Отказоустойчивость (high availability) — система переживает отказ части себя без остановки. Упал узел или целая зона — трафик ушёл на оставшиеся, пользователь ничего не заметил. Это про «продолжать работать».
- Аварийное восстановление (disaster recovery, DR) — как поднять систему после крупной аварии, которая всё-таки её уронила: потеря целого региона, порча данных, ошибочное массовое удаление. Это про «как вернуться к жизни и с какими потерями».
Первое строят заранее в архитектуре; второе — это план и бэкапы, которые понадобятся в худший день.
Первый эшелон: защита от «удалили не то»
Статья сама называет самым частым сценарием не пожар в дата-центре, а человеческую ошибку. Значит, начинать надо не с парных регионов, а с трёх настроек, которые включаются за десять минут и работают сами.
Мягкое удаление в хранилище. Удалённый файл не исчезает, а хранится заданное число дней и восстанавливается одной операцией. Включается на учётной записи хранения — отдельно для объектов и отдельно для контейнеров (удалённый контейнер со всем содержимым тоже восстанавливается). Рядом стоит версионирование: перезапись файла неверными данными откатывается на предыдущую версию.
Неизменяемые резервные копии. Копия, которую можно удалить теми же правами, которыми удалили данные, — не защита. Поэтому у хранилища копий включают мягкое удаление (в современных хранилищах копий оно включено по умолчанию) и неизменяемость: копии нельзя удалить или изменить до конца срока хранения, в том числе администратору. Это ровно та настройка, которая отличает «у нас есть копии» от «у нас есть копии, которые нельзя стереть вместе с данными».
Блокировки ресурсов. Пометка CanNotDelete на боевой группе ресурсов, на базе, на хранилище. Работает независимо от прав: владелец подписки тоже не удалит, пока не снимет блокировку. Разбор — в статье про основы.
Порядок внедрения именно такой: сначала эти три, потом всё остальное. Они дешёвые, не требуют второго региона и закрывают самый вероятный сценарий — тот, в котором никакое оборудование не отказывало.
Зоны и парные регионы
Основной инструмент отказоустойчивости — распределение по зонам доступности одного региона: независимые дата-центры, авария в одном не задевает другие. На практике: копии приложения в масштабируемом наборе по зонам за балансировщиком, управляемая база с зоно-избыточной высокой доступностью и автопереключением.
От крупной аварии всего региона защищает второй регион. У многих регионов Azure для этого есть заранее назначенная пара (region pair) — регион, с которым платформа согласует обновления и в который умеют складывать копию отдельные сервисы.
Две оговорки, без которых эту штуку понимают неправильно. Первая: пара есть не у всех. Часть современных регионов — например, Польша, Израиль, Италия, Катар — создана вообще без пары; там опираются на зоны доступности, а второй регион, если он нужен, выбирают сами. Искать несуществующую пару бессмысленно. Вторая: сам по себе парный регион ничего не реплицирует. Копия появляется там, только если так настроен конкретный сервис — гео-избыточное хранилище у Blob Storage, гео-резервные копии у управляемой базы; для виртуальных машин и приложений нужен отдельный механизм. Это не встроенная репликация, а место, куда её удобно направить. Настраивается отдельно и стоит дороже, зато переживает потерю целого региона.
RPO и RTO: язык восстановления
Планируя восстановление, оперируют двумя числами.
- RPO (Recovery Point Objective) — сколько данных вы готовы потерять, измеряется временем. RPO = 1 час означает «в худшем случае теряем последний час изменений». Определяется частотой резервных копий.
- RTO (Recovery Time Objective) — как быстро надо вернуть сервис к жизни. RTO = 30 минут означает «через полчаса после аварии система снова работает».
Эти два числа — не технические детали, а бизнес-решение: чем меньше RPO и RTO, тем дороже подготовка. Сначала договариваются, что приемлемо, потом строят под это.
Самый частый отказ — не регион, а зависимость на три минуты
Про регионы говорить интереснее, а происходит в жизни другое: база на минуту стала отвечать медленно, соседний сервис вернул ошибку, внешний провайдер отвалился на три минуты. Зоно-избыточная схема тут не помогает вообще — ничего не «упало», всё работает медленно или с ошибками.
Что должно произойти в приложении, чтобы такой сбой не превратился в аварию:
Таймауты на всё. У каждого внешнего вызова свой предел, соразмерный бюджету ответа. Вызов без таймаута — это поток, занятый до тех пор, пока сеть не сдастся; десяток таких вызовов выедает пул потоков, и сервис перестаёт отвечать на все запросы, включая те, которым отказавшая зависимость не нужна.
Повторы с паузой и разбросом. Повторять стоит только то, что может пройти со второй попытки (таймаут, ошибка соединения, 5xx, ограничение частоты) и только если операция идемпотентна. Пауза нарастающая, со случайной добавкой — иначе все клиенты синхронно ударят по поднимающемуся сервису.
Предохранитель. После серии отказов вызовы к зависимости перестают уходить вовсе: сервис сразу возвращает ошибку или деградированный ответ, а раз в несколько секунд пробует одиночный запрос. Это экономит и своё время, и время того, кто поднимается.
Ограничение одновременных вызовов. У каждой зависимости своя квота потоков и соединений, чтобы медленный сосед выедал только её.
Деградация вместо отказа. Отзывы товара не загрузились — показываем карточку без отзывов. Рекомендации недоступны — показываем популярное. Это решение продуктовое, и принимать его надо заранее, по каждому вызову: «что показать, если этого нет».
Асинхронность там, где возможно. Отправка письма, начисление бонусов, обновление индекса — всё это не должно происходить в запросе пользователя. Тогда недоступность этих сервисов вообще не видна снаружи.
И проверка, которая ставит всё на место: намеренно замедлить зависимость на стенде (или оборвать её) и посмотреть, что видит пользователь. Если сервис отвечает ошибкой на всё — таймауты и перегородки не настроены, и никакая схема размещения это не исправит. Подробный разбор приёмов — в статье про устойчивость.
Отказоустойчивость не спасает от порчи или удаления данных: если ошибочный запрос удалил строки, реплики честно повторят удаление. Здесь спасают только копии, отдельные от боевых данных. Что выбрать, зависит от того, что именно нужно вернуть: машину целиком, базу на момент до ошибки или файлы в другом регионе:
- Azure Backup — резервные копии виртуальных машин и баз с заданной частотой и сроком хранения; частота задаёт RPO;
- автоматические копии управляемых баз — с восстановлением на момент в прошлом. У этого окна есть край: в Azure Database for PostgreSQL срок хранения копий настраивается, обычно от 7 до 35 дней, и глубже него восстанавливать уже не из чего. Если данные должны переживать месяцы — это отдельная задача и отдельные копии;
- гео-избыточное хранилище (GRS) для Blob Storage — копия данных во втором регионе. Дешёвый уровень Archive сюда просится, но сверьтесь с RTO, о котором только что шла речь: объект из архива нельзя прочитать, пока его не «разморозят», а это часы. В Archive складывают только те копии, которые точно не понадобятся срочно;
- Azure Site Recovery — сервис, который реплицирует виртуальные машины (облачные и свои, физические) во второй регион и оркестрирует переключение по плану DR. Управляемые сервисы — базу, хранилище, функции — он не переносит: у каждого из них свой механизм, и план DR собирает их отдельно.
Ключевое правило, которое нарушают чаще всего: бэкап, который ни разу не восстанавливали, — это не бэкап, а предположение. Восстановление надо проверять, иначе в худший день выяснится, что копии битые или неполные.
Где это применяется
Практический минимум для боевого сервиса: копии приложения в нескольких зонах за балансировщиком, управляемая база с резервом в другой зоне и автопереключением, регулярные копии с осознанным RPO и хотя бы раз проверенным восстановлением. Этого достаточно, чтобы пережить самые частые сбои без потери данных и с предсказуемым простоем.
Типичные ошибки новичков:
- всё в одной зоне — «отказоустойчивая» система падает целиком при аварии зоны;
- нет резервных копий, потому что «есть же реплики» — реплики повторяют и ошибочное удаление;
- никогда не проверяли восстановление — узнают о битых бэкапах в день аварии;
- не договорились про RPO/RTO — строят наугад, переплачивая или недозащищаясь.
Глубже: гео-избыточность включают при созданиирасширенное
Практическая ловушка, из-за которой план восстановления не работает в самый нужный момент: часть настроек восстановления в другом регионе нельзя включить потом.
У управляемого PostgreSQL резервное копирование в парный регион (гео-избыточное) выбирается при создании сервера. Забыли — и включить его у работающего сервера нельзя: придётся создавать новый сервер с этой настройкой и переносить данные. То же относится к нескольким другим сервисам: выбор вида избыточности хранилища копий, включение записи в нескольких регионах у документной базы, парный регион у некоторых ресурсов.
Отсюда правило: решение про восстановление в другом регионе принимают в момент создания ресурса, а не когда приходит требование. Стоит это обычно проценты к цене, а переделка — отдельный проект с переносом данных.
Что стоит проверить на своих боевых ресурсах прямо сейчас, одним проходом: включено ли гео-избыточное копирование у баз; какой вид избыточности у учётных записей хранения (локальная в одном дата-центре, зональная, гео-избыточная); включено ли восстановление в другой регион там, где оно отдельная настройка. Пять минут, и вы знаете, есть ли у вас вообще техническая возможность подняться в другом регионе.
Глубже: в план восстановления входят не только данныерасширенное
Список, который обнаруживают на первом же учении: данные восстановили, а сервис не поднялся, потому что не хватило всего остального.
Конфигурация. Настройки приложений, строки подключения, признаки включённых возможностей — всё это живёт в самих ресурсах и в другом регионе отсутствует. Ответ: конфигурация описана кодом (см. статью про инфраструктуру как код) и разворачивается вместе с ресурсами.
Секреты и ключи. Хранилище секретов — региональный ресурс; его содержимое в другом регионе не появится само. Нужна либо репликация секретов, либо восстановление из копии. Отдельно: ключи шифрования. Данные, зашифрованные ключом из хранилища в упавшем регионе, в другом регионе не расшифруются — это классическая причина «копии есть, восстановиться не можем».
Образы контейнеров. Реестр тоже региональный. Если он недоступен, поднять приложение не из чего; лечится гео-репликацией реестра или правилом «свежий образ каждой боевой версии есть во втором реестре».
Имена и сертификаты. Переключение трафика делается записями в службе имён, и работает время жизни записи: значение в час означает, что часть пользователей будет идти в мёртвый регион ещё час. Значит, короткое время жизни настраивают заранее. Сертификаты для второго региона выписывают тоже заранее — в момент аварии их выпуск и проверка домена превращаются в лишние часы.
Квоты. В резервном регионе они по умолчанию низкие, а заявка обрабатывается от минут до суток. Поднимают заранее и сверяют раз в полгода.
Права и доступы. У дежурного должны быть права на переключение в резервном регионе и работающий вход, когда основной контур недоступен.
Сам код развёртывания. Конвейер, который разворачивает приложение, тоже где-то живёт. Если он зависит от ресурсов в упавшем регионе, поднять сервис вручную окажется единственным вариантом — и делать это по памяти никто не должен.
Проверяется весь список одним способом: учением, о котором ниже. Читать его глазами бесполезно — каждый раз находится восьмой пункт, которого в списке не было.
Глубже: учения: как проверить восстановлениерасширенное
«Восстановление надо проверять» без процедуры остаётся пожеланием. Вот как это делают.
Что считается учением. Восстановление из копии в отдельную среду и проверка двух вещей: данные целы (не просто файл открылся, а сверены контрольные суммы или пересчитаны итоги) и вы уложились в свой RTO (время замеряется от начала до момента, когда сервис отвечает).
Периодичность. Копии баз — раз в квартал; полное восстановление сервиса в другом регионе — раз в полгода или год; проверка отдельных элементов (переключение базы, отказ зоны) — чаще, они дешёвые. Важнее регулярности другое: учение проводят после каждого крупного изменения архитектуры, потому что именно тогда план устаревает.
Что считается успехом. Не «восстановились», а три числа: за сколько восстановились (сравнить с RTO), сколько данных потеряли (сравнить с RPO) и сколько шагов пришлось делать не по документу. Последнее — самый полезный показатель: каждый такой шаг дописывают в процедуру.
Как не сломать боевой контур. Восстановление всегда идёт в отдельную среду или в отдельную группу ресурсов; переключение трафика на учении не делают, если не договорились отдельно. Для проверки отказов есть управляемый инструмент внесения сбоев (Azure Chaos Studio) с условиями остановки — им гасят экземпляры, отключают зону, добавляют задержку, и он сам всё возвращает при превышении порога ошибок.
Результат учения — правки. Короткий отчёт: что не сработало как ожидали, чего не хватило, какие пункты добавить в план. Если после учения ничего не поправили, оно было формальным.
И то, что стоит потренировать отдельно, потому что об этом забывают: возврат в основной регион. Команда, которая переключалась и ни разу не возвращалась, в реальной аварии остаётся в резервном регионе на недели.
Глубже: RPO и RTO в деньгахрасширенное
Метрики полезны, когда видно их цену — иначе бизнес называет «ноль и ноль». Порядок величин на примере одного сервиса с базой:
| Требование | Как это устроено | Относительная цена |
|---|---|---|
| RPO сутки, RTO сутки | ежедневные копии, восстановление вручную | 5–10 % от стоимости контура (только хранение копий) |
| RPO часы, RTO часы | копии чаще плюс готовые описания инфраструктуры | 10–20 % |
| RPO минуты, RTO десятки минут | репликация базы в другой регион, инфраструктура описана кодом и разворачивается по кнопке | 30–50 % |
| RPO близко к нулю, RTO минуты | полная копия в другом регионе, постоянно работающая | 100 % и больше |
То есть переход от «потеряем сутки» к «потеряем минуты» стоит примерно в три-пять раз дороже, а к «не потеряем ничего» — вдвое от всей инфраструктуры. Разговор с бизнесом после этой таблицы становится предметным: не «сколько вы готовы потерять», а «готовы ли вы платить вдвое, чтобы не потерять последние пять минут заказов».
И обратный вопрос, который стоит задать заранее: сколько стоит час простоя для вашего сервиса. Если ответ «ничего страшного» — верхние строки таблицы вам и не нужны; если «сто тысяч» — нижние окупаются мгновенно.
Коротко
- Отказоустойчивость переживает отказ части системы без остановки, восстановление поднимает систему после крупной аварии; первое строят в архитектуре, второе это план и копии.
- Первый эшелон включают за десять минут: мягкое удаление в хранилище, неизменяемые копии, блокировка CanNotDelete на боевых группах; они закрывают самый вероятный сценарий, где никакое оборудование не отказывало.
- Зоны одного региона против отказа дата-центра, второй регион против аварии региона; пара регионов есть не у всех, и её обновления идут не одновременно.
- RPO это сколько данных теряем, RTO как быстро поднимаемся; оба числа называет бизнес, и цена растёт от копий раз в сутки за 5–10 % до постоянной копии в другом регионе за 100 % и больше.
- Самый частый отказ это зависимость на три минуты: таймауты на всё, повторы с паузой и разбросом только для идемпотентного, предохранитель, ограничение одновременных вызовов, деградация и асинхронность.
- Реплики повторяют ошибочное удаление: спасают Azure Backup, автоматические копии баз с ограниченным окном, GRS для хранилища и Site Recovery для машин; копия, которую не восстанавливали, это предположение.
- Гео-избыточное копирование базы включают при создании сервера и потом не включить: решение о втором регионе принимают в момент создания ресурса.
- В план входят конфигурация кодом, репликация секретов и ключей, образы во втором реестре, короткий TTL записей DNS, квоты и права дежурного в резервном регионе, конвейер вне упавшего региона.
- Учение это восстановление в отдельную среду с проверкой данных и времени против RPO и RTO, раз в квартал для копий баз и раз в полгода целиком, с обязательными правками по итогам и тренировкой возврата.
Что почитать дальше
- Масштабирование и доступность в Azure — как строится доступность в норме.
- Blob Storage — где хранят копии и что такое избыточность.
- Основы Azure — блокировки и зоны, на которых стоит первый эшелон.
- Отказоустойчивость и восстановление в облаке — та же пара задач без привязки к провайдеру.