«Управляемый» (managed) сервис — это когда вы пользуетесь технологией, а её обслуживанием занимается провайдер. Своя база на сервере — это вы сами ставите PostgreSQL, настраиваете копии, по ночам чините. Управляемая база — та же PostgreSQL, но копии, замену сломанного узла и обновления делает Google. Вы платите за это деньгами, но не временем и не бессонными ночами.
Главная ценность облака для backend-разработчика — не виртуальные машины, а именно управляемые данные: базы, кэши, очереди и брокеры. Эта статья — карта соответствий «то, что вы знаете по своему серверу → как это называется в GCP», и честный список того, что managed-сервис за вас не делает.
Четыре управляемых хранилища и то, что остаётся вашим у каждого: пул и способ подключения у базы, выбор уровня у кэша, идемпотентность и тема для недоставленных у очереди, а отчёты уезжают в BigQuery, чтобы не мешать рабочей базе.
Cloud SQL
Диск под базой заполнился в три часа ночи, а резервная копия последний раз снималась вручную месяц назад. Cloud SQL — реляционные базы под управлением Google: PostgreSQL, MySQL и SQL Server. Cloud SQL for PostgreSQL — тот же PostgreSQL, только вокруг него автоматика: резервные копии с восстановлением на момент в прошлом, конфигурация высокой доступности с резервом в другой зоне, обновления версий, реплики для чтения. Аналог RDS в AWS.
Главное для новичка: managed-база снимает с вас эксплуатацию железа, но не проектирование данных. Она спасёт от сгоревшего диска, но не от запроса SELECT без индекса, перебирающего миллион строк. Схема, индексы, блокировки, безопасные миграции, тюнинг запросов — по-прежнему ваша работа.
И ещё одна вещь, которую managed-сервис за вас не делает, — пул соединений. PostgreSQL заводит отдельный процесс на каждое соединение, и лимит у экземпляра невелик: десяток копий сервиса с жадным пулом выедают его целиком, а новые подключения начинают падать с отказом. Готового посредника вроде RDS Proxy из AWS в Cloud SQL долго не было вовсе — пул держали в самом приложении (HikariCP, pgxpool, пул pg, пул SQLAlchemy) или ставили рядом PgBouncer. Сейчас у Google есть и встроенный управляемый пул, но он доступен только на редакции Enterprise Plus, так что по умолчанию соединения считаете вы.
Подключаются к Cloud SQL не по внешнему IP, а через Cloud SQL-коннектор (или Auth Proxy) — прослойку, которая сама поднимает шифрованный канал и подтверждает право дойти до экземпляра по сервисному аккаунту, так что публичный адрес базе не нужен. Только не решите, что пароль при этом исчез: коннектор отвечает за канал и за право постучаться, а дальше вас встречает обычная аутентификация PostgreSQL — пользователь и пароль, и их всё так же берут из секретов. Убрать пароль совсем можно, но это отдельная настройка — аутентификация базы через IAM, когда вместо пароля подставляется токен сервисного аккаунта.
Для нагрузок, которым мало обычного PostgreSQL, есть AlloyDB — PostgreSQL-совместимая база Google с повышенной производительностью.
Чего управляемый PostgreSQL не даёт
«Снимает эксплуатацию, но не проектирование» — верно и абстрактно. Конкретно при переезде со своего сервера вы теряете следующее.
Суперпользователя. Учётная запись, которую вы получаете, имеет широкие права, но не SUPERUSER. Часть команд обслуживания, чтение файлов сервера и произвольные расширения недоступны.
Произвольные расширения. Доступен список, который определяет платформа (в нём десятки популярных — pg_stat_statements, postgis, pgvector, pg_trgm), но не всё. Проверять надо до переезда: SELECT * FROM pg_available_extensions; на пробном экземпляре.
Правку postgresql.conf. Вместо неё — флаги базы (--database-flags), и не все параметры доступны. Часть изменений требует перезапуска, то есть окна.
Произвольные версии. Версии PostgreSQL из списка поддерживаемых; самая свежая появляется с задержкой, а самая старая однажды выводится из поддержки.
Бесшовное обновление старшей версии. Переход с одной старшей версии на другую — отдельная операция с простоем (порядка десятков минут, зависит от размера). Планируют её как работы, а не как «обновим на ходу»; есть и путь без простоя через реплику, но он сложнее.
Число соединений. Предел зависит от объёма памяти выбранного размера: у маленьких экземпляров это сотня-две. Каждое соединение PostgreSQL — отдельный процесс со своей памятью, отсюда и потолок. Сумму пулов всех приложений сверяют с этим числом, а для множества короткоживущих клиентов ставят пулер.
Что взамен: копии, восстановление на момент времени, переключение при отказе, обновления младших версий, метрики и журналы без настройки. Обычно это стоит перечисленных ограничений — но список стоит прочитать до переезда, а не после.
Числа, по которым принимают решения
| Что | Порядок величины |
|---|---|
| Соединений у небольшого экземпляра базы | сотня-две, зависит от памяти |
| Переключение базы на резервный экземпляр | около минуты, с обрывом соединений |
| Автоматические копии базы | по умолчанию хранятся около недели, настраивается |
| Восстановление на момент времени | внутри срока хранения копий, создаёт новый экземпляр |
| Размер сообщения в очереди | до 10 МБ |
| Срок хранения сообщений в очереди | по умолчанию 7 дней (настраивается до 31) |
| Пропускная способность очереди | десятки и сотни тысяч сообщений в секунду, без настройки |
| Простой небольшого экземпляра базы | десятки долларов в месяц, вдвое дороже в режиме высокой доступности |
Что из этого чаще всего меняет решения. Переключение рвёт соединения — значит, приложение обязано переподключаться, и это код, а не настройка. Восстановление создаёт новый экземпляр — значит, в процедуре восстановления есть шаг «переключить приложение на новый адрес», и его надо написать заранее. Сообщение до 10 МБ — значит, в сообщении едет ссылка, а не файл. И режим высокой доступности удваивает цену — это осознанное решение, а не галочка по умолчанию.
Memorystore
Кэш — быстрое временное хранилище, куда кладут уже посчитанный результат, чтобы не считать заново. Memorystore — управляемый Redis (а также Valkey и Memcached): кластер, реплики и переключение при сбое настраивает облако. Аналог ElastiCache в AWS.
Применяют как обычный Redis: кэширование ответов с временем жизни (TTL), распределённая блокировка, ограничение частоты запросов. Главное правило новичку: кэш — это не база данных. Данные, потеря которых недопустима (заказы, платежи), в нём не хранят: кэш может сбросить содержимое в любой момент.
Два режима кэша: с репликой и без
У управляемого Redis есть уровни, и разница между ними — не в скорости, а в том, переживёт ли кэш отказ узла.
Базовый уровень — один узел, без реплики. Отказ узла означает: кэш недоступен на время пересоздания, и всё содержимое потеряно. Для чистого кэша это терпимо (промахи, повышенная нагрузка на базу, восстановление за минуты), для блокировок и сессий — нет.
Стандартный уровень — узел плюс реплика в другой зоне с автоматическим переключением. Отказ узла означает переключение за десятки секунд, содержимое сохраняется (с оговоркой про асинхронную репликацию — последние записи могут потеряться).
Выбор простой: всё, что живёт только в кэше и нужно для работы, требует стандартного уровня. Сессии пользователей, распределённые блокировки, счётчики ограничения частоты — это данные, потеря которых видна пользователю. Кэш результатов запросов — базовый уровень допустим.
И два свойства, которые стоит знать в любом режиме. Политика вытеснения при заполнении памяти задаётся настройкой: для чистого кэша ставят вытеснение любых ключей по давности, а если в кэше лежат блокировки — только ключей со сроком жизни, иначе вытесненная блокировка означает двух исполнителей одной задачи. И обслуживание платформы (обновление версии) — это тоже перезапуск с потерей содержимого на базовом уровне и с переключением на стандартном.
Pub/Sub
Заказ оформлен — и о нём должны узнать трое: сервис чеков, уведомления и аналитика, каждый в своём темпе и не завися от остальных. Pub/Sub — управляемый сервис обмена сообщениями, который в GCP закрывает сразу две роли: и очередь задач, и поток событий. Издатель шлёт сообщение «заказ оформлен» в тему (topic), а получает его каждая подписка (subscription) этой темы: чеки, уведомления и аналитика читают одну и ту же тему независимо.
Это развязывает отправителя и получателя: приложение публикует событие и идёт дальше, а обработчики разгребают их в своём темпе. Так сглаживают всплески, не теряют задачи и строят событийные системы.
Счастливый путь здесь простой — «отправили и получили». Ломается всё на правилах, которые новичок узнаёт уже в бою:
- доставка не менее одного раза — одно и то же сообщение может прийти дважды, например если подтверждение не успело дойти. Обработчик обязан быть идемпотентным: повтор не должен создавать второй заказ;
- порядок не гарантирован — сообщения приходят как придётся, пока вы явно не включили упорядочивание у подписки и не проставили ключ упорядочивания в каждом сообщении;
- на подтверждение есть срок — по умолчанию 10 секунд: не успели подтвердить, сообщение считают недоставленным и присылают снова. Долгую обработку либо продлевают явно, либо разбивают на короткие шаги;
- сообщения не лежат вечно — по умолчанию подписка хранит неподтверждённое сообщение 7 дней, максимум 31. Обработчик, который чинят две недели, — это потерянные сообщения;
- есть очередь недоставленных — чтобы «ядовитое» сообщение не крутилось по кругу, подписке задают тему для недоставленных (dead-letter topic): после нескольких неудачных попыток, по умолчанию пяти, оно уезжает туда и перестаёт мешать остальным.
Pub/Sub часто служит триггером для Cloud Functions и Cloud Run. Для задач, где нужен именно протокол Apache Kafka, есть отдельный Managed Service for Apache Kafka; устройство самого Kafka разбирает раздел Kafka.
Отдельно стоит назвать BigQuery — хранилище для аналитики. Туда складывают события и отчётные данные и считают по ним запросы на терабайтах, платя за объём просканированного. Рабочую базу сервиса он не заменяет: у Cloud SQL короткие запросы за конкретной строкой, у BigQuery — долгие по всей таблице. Но в карте GCP его не пропустить: в Google Cloud часто приходят как раз ради BigQuery, а рядом с ним уже ставят всё остальное.
Как сервис видит базу без публичного адреса
Сказано, что у базы нет публичного адреса, и остаётся вопрос, какой механизм это обеспечивает. Он называется приватный доступ к сервисам и устроен не так, как в других облаках.
База живёт не в вашей сети, а в сети, которой управляет Google. Чтобы она получила адрес, видимый из вашей сети, вы выделяете в своей сети диапазон адресов специально для управляемых сервисов и создаёте связь:
gcloud compute addresses create google-managed-services-range \
--global --purpose=VPC_PEERING --prefix-length=16 --network=app-vpc
gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com \
--ranges=google-managed-services-range --network=app-vpc
gcloud sql instances create orders-db --database-version=POSTGRES_16 \
--region=europe-west4 --network=app-vpc --no-assign-ip
Последняя команда и создаёт базу без публичного адреса: она получает адрес из выделенного диапазона, и приложение в той же сети обращается к ней как к внутреннему ресурсу.
Три вещи, которые важно знать. Диапазон выделяют заранее и с запасом (/16 — обычный выбор): его расширение потом отдельная операция. Связь не транзитивна — база, подключённая к сети A, не видна из сети B, даже если A и B связаны между собой; это самая частая причина «из другого проекта база недоступна», и лечится она либо общей сетью, либо точками входа (Private Service Connect). И для сервисов, которые живут вне сети (Cloud Run, функции), нужен либо соединитель с сетью, либо тот же механизм точек входа — то есть выбор способа размещения приложения и способа доступа к базе принимают вместе.
Отдельно стоит знать про соединитель для базы (Cloud SQL Auth Proxy или встроенные соединители в библиотеках): он подключается к базе по её внутреннему пути через API, проверяя права по служебной учётной записи, — то есть шифрование и аутентификация приезжают из платформы, а не из строки подключения с паролем. Для приложения это обычно самый простой путь: разбор — в статье про подключение из кода.
Перенос своей базы в облако
Естественное продолжение темы «то, что вы знаете по своему серверу»: как перевезти работающую базу.
Разовый перенос дампом — то, что подходит для маленьких баз и для стендов: выгрузили, залили, переключили. Простой считается от объёма: гигабайты — минуты, сотни гигабайт — часы.
Перенос без простоя делает отдельный сервис — Database Migration Service. Схема такая: он поднимает в облаке экземпляр-получатель, переливает данные и дальше продолжает применять изменения из источника (через логическую репликацию PostgreSQL). Вы дожидаетесь, когда отставание станет близким к нулю, и переключаете приложение — простой сводится к минутам.
Что нужно подготовить со стороны источника: доступ по сети (туннель или разрешённые адреса), настройки для логической репликации (уровень записи журнала, слоты), и учётная запись с нужными правами. Это та часть, которая занимает время; сам перенос идёт сам.
Три вещи, которые проверяют до переключения: все расширения доступны в облаке (см. список выше), версия совпадает или обновление запланировано, и последовательности и права перенеслись (частая ошибка — приложение работает, а вставка падает, потому что значение последовательности осталось прежним).
И порядок переключения, который стоит написать заранее: остановить запись в источник → дождаться нулевого отставания → переключить приложение на новый адрес → проверить по контрольным запросам → и только потом остановить репликацию. Обратный путь (вернуться на источник) должен быть возможен хотя бы первые сутки.
Управляемый против своего: как выбирать
| Управляемый | Свой на сервере | |
|---|---|---|
| Эксплуатация | Копии, переключение, обновления — облако | Всё ваше, включая три часа ночи |
| Цена | Надбавка к стоимости железа | Дешевле железом, дороже людьми |
| Контроль | Версии и параметры из списка облака | Любые расширения и тонкая настройка |
Разумное правило: компоненты с состоянием (базы, кэши, очереди) берём управляемыми, пока нет конкретной причины делать иначе. Прежде чем самому обслуживать базу при доступном managed-сервисе, честно ответьте, на что команда потратит время, которое сервис ей освобождает.
Где это применяется
Управляемые данные — костяк почти любого сервиса: база под основные данные, кэш перед ней, Pub/Sub для фоновых задач и событий. Всё это живёт во внутренней сети без внешних адресов и доступно приложению через привязанный сервисный аккаунт.
Типичные ошибки новичков:
- хранят важные данные в кэше — теряют при сбросе;
- подключаются к Cloud SQL по внешнему IP вместо коннектора — открывают базу наружу;
- берут свой сервер там, где хватило бы managed;
- выедают лимит соединений к базе без пулера.
Глубже: BigQuery: аналитика рядом с базой, а не в нейрасширенное
BigQuery упомянут выше одним абзацем, а это сервис, ради которого команды выбирают GCP, и первое место, куда уезжают отчёты из Cloud SQL и Firestore. Его устройство противоположно рабочей базе, и на этом строится всё остальное.
Данные лежат по колонкам в хранилище Google, а запросы выполняет пул машин, которого у вас нет: ни кластера, ни настроек памяти, ни индексов. Запрос по терабайту читает только нужные колонки и раскладывается на тысячи машин, поэтому агрегат по миллиарду строк отвечает за секунды. Платят за объём просканированных данных (порядка шести долларов за терабайт при оплате по запросам) и за хранение (около двух центов за гигабайт в месяц, вдвое дешевле для таблиц, которые не меняли три месяца). Отсюда главный навык: секционировать таблицы по дате и кластеризовать по частым фильтрам, чтобы запрос за вчера сканировал день, а не год; SELECT * по несекционированной таблице это самый дорогой запрос в GCP.
Данные попадают туда несколькими путями. События из Pub/Sub пишутся напрямую подпиской BigQuery без кода. Изменения из Cloud SQL переносит Datastream, сервис репликации изменений в BigQuery почти в реальном времени. Файлы из Cloud Storage загружаются пакетами или читаются на месте внешней таблицей. Экспорт биллинга в BigQuery включается галочкой, и после этого счёт за облако разбирают запросами, о чём статья про затраты.
Чего BigQuery не делает: не заменяет рабочую базу. Обновление и удаление отдельных строк там дорого и ограничено по частоте, задержка любого запроса это секунды, а не миллисекунды, транзакций для приложения нет. Правильная связка: Cloud SQL держит текущее состояние и отвечает приложению, BigQuery получает поток событий и историю и отвечает аналитикам и отчётам. Между ними Pub/Sub или Datastream, и никогда не прямой запрос приложения к BigQuery на каждый клик пользователя. Как та же граница проводится вообще, разбирает статья про PostgreSQL против ClickHouse.
Коротко
- Cloud SQL снимает эксплуатацию железа, но не проектирование данных; подключаются через коннектор, а не по внешнему IP; пул соединений и лимит экземпляра остаются вашими.
- Memorystore это управляемый Redis: кэш, блокировки, лимиты, и не база данных.
- Pub/Sub доставляет хотя бы один раз без порядка, с сроком подтверждения 10 секунд и хранением 7 дней; идемпотентный обработчик и тема для недоставленных обязательны.
- Компоненты с состоянием берут управляемыми, пока нет конкретной причины.
- BigQuery это аналитика по колонкам с оплатой за просканированное: секционировать по дате, кластеризовать по фильтрам, питать из Pub/Sub и Datastream, не использовать как рабочую базу.
- Управляемый PostgreSQL не даёт суперпользователя, произвольных расширений и правки файла настроек, а обновление старшей версии — отдельная операция с простоем; предел соединений зависит от памяти экземпляра.
- Переключение базы рвёт соединения, а восстановление создаёт новый экземпляр — и то и другое должно быть учтено в коде и в процедуре.
- У кэша два уровня: без реплики содержимое теряется при отказе узла, с репликой переживает переключение; сессии и блокировки требуют второго.
- Базу без публичного адреса даёт приватный доступ к сервисам: диапазон выделяют заранее с запасом, связь не транзитивна, а для сервисов вне сети нужен соединитель или точка входа.
- Перевезти свою базу без простоя помогает служба переноса с логической репликацией: до переключения проверяют расширения, версию, права и значения последовательностей.
Что почитать дальше
- Firestore и другие NoSQL — документная база, когда реляционная модель не подходит.
- Cloud Storage — файлы и объекты, откуда BigQuery читает внешние таблицы.
- Serverless в GCP — Pub/Sub как триггер и повторы доставки.