«А что будет, когда это сломается?» — вопрос, который отличает боевую систему от учебной. Сломается обязательно: упадёт узел, выйдет из строя зона, кто-то удалит не ту таблицу. Разница между катастрофой и штатной ситуацией — в том, подготовились ли вы заранее. Разберём два уровня подготовки. Оба стоят на нескольких зонах, поэтому начните с масштабирования и доступности, если ещё не читали.

отказ зоны копии по зонам Cloud SQL с резервом сервис отвечает удалили проект копия в другом проекте блокировка хранения восстановление за RTO отказ региона межрегиональная реплика повышение до базы глобальный балансировщик переводит трафик

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

Обязательно

Отказоустойчивость против аварийного восстановления

Это два разных уровня, их полезно различать.

  • Отказоустойчивость (high availability) — система переживает отказ части себя без остановки. Упал узел или целая зона — трафик ушёл на оставшиеся, пользователь ничего не заметил. Это про «продолжать работать».
  • Аварийное восстановление (disaster recovery, DR) — как поднять систему после крупной аварии, которая всё-таки её уронила: потеря целого региона, порча данных, ошибочное массовое удаление. Это про «как вернуться к жизни и с какими потерями».

Первое строят заранее в архитектуре; второе — это план и бэкапы, которые понадобятся в худший день.

Зоны и мультирегион

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

От крупной аварии всего региона защищает мультирегиональная схема: копии приложения в нескольких регионах за глобальным балансировщиком (он сам направит пользователей в живой регион) и данные, реплицируемые между регионами. Это дороже и настраивается отдельно, но переживает потерю целого региона. Глобальный HTTP-балансировщик здесь один на все регионы, с одним anycast-адресом: не нужно ни DNS-переключения, ни отдельного балансировщика в каждом регионе, а пользователей он направляет в ближайший живой регион сам.

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

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

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

1. Копии и восстановление. Вы храните резервные копии, и всё. Случилась беда — разворачиваете инфраструктуру заново и заливаете данные. Дешевле некуда (платите только за хранение копий), а восстановление занимает часы и требует, чтобы описание инфраструктуры было под рукой и работало.

2. Дежурная лампочка. Постоянно работает только ядро — обычно межрегиональная реплика базы, которая получает свежие данные. Приложение, балансировщики и остальное выключено и поднимается при аварии. Восстановление — десятки минут, и потеря данных ограничена отставанием реплики (секунды-минуты, потому что репликация асинхронная).

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

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

Порядки величин, чтобы сопоставлять со требованиями:

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

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

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

RPO и RTO: язык восстановления

Планируя восстановление, оперируют двумя числами.

  • RPO (Recovery Point Objective) — сколько данных вы готовы потерять, измеряется временем. RPO = 1 час означает «в худшем случае теряем последний час изменений». Определяется частотой резервных копий.
  • RTO (Recovery Time Objective) — как быстро надо вернуть сервис к жизни. RTO = 30 минут означает «через полчаса после аварии система снова работает».

Эти два числа — не технические детали, а бизнес-решение: чем меньше RPO и RTO, тем дороже подготовка. Сначала договариваются, что приемлемо, потом строят под это.

Резервные копии и репликация

Отказоустойчивость не спасает от порчи или удаления данных: если ошибочный запрос удалил строки, реплики честно повторят удаление. Здесь спасают только копии, отдельные от боевых данных:

  • автоматические резервные копии Cloud SQL — снимок базы по расписанию. Сам по себе он задаёт RPO, равный промежутку между копиями: копия раз в сутки — значит, в худшем случае теряется день работы;
  • восстановление на момент в прошлом (PITR) — отдельная возможность поверх копий: база хранит журналы транзакций, и вернуться можно на конкретную минуту, а не только на момент копии. Именно она превращает RPO из «суток» в «минуты» — но включена она не всегда и не везде: зависит от редакции Cloud SQL и от того, чем вы создавали экземпляр, консолью или Terraform. Проверьте у себя, а не считайте, что это есть по умолчанию;
  • снимки дисков (snapshots) виртуальных машин — точечная копия состояния диска. С базой, живущей на такой машине, есть подвох: снимок работающей базы не согласован на уровне приложения. Вы копируете диск в произвольный момент, когда часть данных ещё в памяти и в незавершённых записях, — и получаете не бэкап, а его видимость. Чтобы снимок был рабочим, запись на время останавливают или заставляют базу сбросить буферы на диск;
  • версионирование в Cloud Storage — защита от перезаписи и удаления: прежняя версия объекта остаётся рядом, и её можно вернуть. В ту же сторону работает мягкое удаление (soft delete), которое Google включает у новых бакетов по умолчанию: удалённое и перезаписанное ещё несколько дней (по умолчанию 7) лежит скрытым и восстанавливается;
  • мультирегиональные бакеты — совсем про другое: они спасают не от кривого скрипта, а от потери региона, потому что держат копии файлов в нескольких регионах. Сами бэкапы при этом часто складывают в дешёвый класс Archive.

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

Самый вероятный сценарий: удалили

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

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

Что включают, чтобы этого не случилось:

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

gcloud compute instances update app-1 --deletion-protection
gcloud sql instances patch orders-db --deletion-protection

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

Блокировка хранения на бакете с копиями. Политика хранения с блокировкой делает удаление объектов невозможным до истечения срока — для всех, включая владельца. Разбор — в статье про объектное хранилище; для темы восстановления это опорный механизм.

Ограничение прав на удаление. Роль, которая позволяет создавать и менять, но не удалять, — обычная практика для команд; право удалять остаётся у узкой группы или только у конвейера.

Порядок внедрения: сначала это (дёшево, быстро, закрывает самый вероятный сценарий), потом высокая доступность в регионе, и только потом второй регион.

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

Практический минимум для боевого сервиса: копии приложения в нескольких зонах за балансировщиком, Cloud SQL с резервом в другой зоне и автопереключением, регулярные копии с осознанным RPO и хотя бы раз проверенным восстановлением. Этого достаточно, чтобы пережить самые частые сбои без потери данных и с предсказуемым простоем.

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

  • всё в одной зоне — «отказоустойчивая» система падает целиком при аварии зоны;
  • нет резервных копий, потому что «есть же реплики» — реплики повторяют и ошибочное удаление;
  • никогда не проверяли восстановление — узнают о битых бэкапах в день аварии;
  • не договорились про RPO/RTO — строят наугад, переплачивая или недозащищаясь.
Дополнительно: при первом чтении можно пропустить

Глубже: резерв базы это не реплика для чтениярасширенное

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

Резервный экземпляр не читается вовсе. Он существует только для переключения при отказе: данные на него приходят синхронно, но подключиться к нему нельзя. Это не удвоение мощности и не место для аналитики — это страховка.

Реплика для чтения — отдельный ресурс. Её создают явно, она асинхронная (отстаёт), и с неё читают тяжёлые запросы и отчёты. Отставание обычно небольшое, но «прочитать только что записанное» с неё нельзя — это надо учитывать в коде.

Для восстановления региона нужна межрегиональная реплика. Режим высокой доступности работает внутри региона (резерв в другой зоне) и не спасает от отказа региона целиком. Чтобы иметь возможность подняться в другом регионе, создают реплику в другом регионе — и именно её при аварии повышают до самостоятельной базы.

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

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

Глубже: как проверять восстановлениерасширенное

«Копия, из которой не восстанавливали, — не копия» — правило, у которого должна быть процедура.

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

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

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

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

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

Результат учения — не отчёт «успешно», а список правок в процедуре и в инфраструктуре. Если после учения ничего не поправили, оно было формальным.

Коротко

  • Отказоустойчивость переживает отказ части системы без остановки, восстановление поднимает систему после крупной аварии; первое строят в архитектуре, второе это план и копии.
  • Зоны одного региона против отказа дата-центра, мультирегион с глобальным балансировщиком против аварии региона; репликация между регионами асинхронная, и последние секунды записей теряются.
  • Четыре стратегии по возрастанию цены: копии и восстановление, дежурная лампочка с межрегиональной репликой, тёплый резерв, две живых площадки; берут первую сверху, которая укладывается в RPO и RTO, а в GCP переход к второй дёшев благодаря коду инфраструктуры.
  • RPO это сколько данных теряем, RTO как быстро поднимаемся; оба числа называет бизнес.
  • Реплики повторяют ошибочное удаление: спасают копии Cloud SQL по расписанию, PITR по журналам, снимки дисков с оговоркой о согласованности, версионирование и мягкое удаление в Cloud Storage; копия, которую не восстанавливали, это предположение.
  • Резерв высокой доступности не читается, реплика для чтения это отдельный асинхронный ресурс, а для восстановления региона нужна межрегиональная реплика; переключение занимает минуту и рвёт соединения.
  • Самый вероятный сценарий это удаление, в GCP вплоть до всего проекта: защита от удаления у ресурсов, копии в проекте с другими правами, блокировка хранения на бакете, право удалять у узкой группы.
  • Учения: раз в квартал восстановить копию в отдельный проект, замерить время, потерю и шаги мимо документа, проверить секреты, образы и права, принудительно переключить базу и потренировать возврат.

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