> Вы используете один кластер или геораспределенную систему? (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: InDrive
Стек: Go
> Пример ответа
Короткий ответ
В продакшене мы используем один основной кластер с синхронной репликацией в несколько зон доступности одного региона. Для глобального охвата применяем отдельные read-only реплики в других регионах, но запись всегда идёт в основной кластер. Это даёт консистентность и упрощает операции, хотя и добавляет задержку для удалённых пользователей. Геораспределённая мульти-мастер схема - осознанный trade-off, который мы пока не готовы принять из-за сложности разрешения конфликтов.
Подробное объяснение
Выбор между одним кластером и геораспределённой системой - это всегда компромисс между консистентностью, доступностью и задержкой. Для нашего продукта критична строгая консистентность на уровне транзакций: финансовые операции, инвентаризация, балансы. Один кластер с синхронной репликацией в пределах региона даёт нам:
- ACID-транзакции без компромиссов
- единую точку истины для всех сервисов
- предсказуемое поведение при сбоях (failover в пределах региона)
- упрощённое резервное копирование и восстановление
Геораспределённая система с мульти-мастер репликацией решает проблему задержек, но создаёт новые: конфликты записи, частичные сбои, сложная логика разрешения конфликтов. Мы используем гибридный подход: основной кластер в одном регионе, read-only реплики в других. Это позволяет обслуживать чтение локально, а запись - с задержкой до основного региона. Для большинства сценариев (лента, профиль, каталог) этого достаточно.
Если бы мы строили систему с нуля для глобального продукта с требованием записи из любой точки мира, я бы рассматривал CockroachDB или YugabyteDB с настройкой топологии. Но миграция существующей системы на такую архитектуру - это проект на годы, и текущий подход даёт нужный баланс.
На практике
В нашем Go-стеке это выглядит так:
- Основной кластер PostgreSQL (или CockroachDB) в регионе
eu-central-1 - Синхронная репликация в
eu-central-2иeu-central-3(quorum commit) - Read-only реплики в
us-east-1,ap-southeast-1для локального чтения - Приложение подключается через пул соединений (pgxpool) с указанием роли: primary для записи, replica для чтения
- Для маршрутизации запросов используем middleware, который определяет тип запроса (GET - чтение, остальное - запись) и направляет на соответствующий endpoint
- Мониторинг задержек репликации через
pg_stat_replicationи алерты при лаге более 100 мс
Если пользователь из Азии делает запись, запрос идёт в eu-central-1 (RTT ~200 мс). Это приемлемо для наших сценариев - операции записи редкие и не критичны к задержке. Для чтения - локальная реплика, задержка минимальна.
Пример кода
GOtype DBSelector struct {primary *pgxpool.Poolreplicas []*pgxpool.Poolrr int}func (s *DBSelector) GetPool(r *http.Request) *pgxpool.Pool {if r.Method == http.MethodGet {s.rr = (s.rr + 1) % len(s.replicas)return s.replicas[s.rr]}return s.primary}// middlewarefunc DBMiddleware(selector *DBSelector, next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {ctx := context.WithValue(r.Context(), "db", selector.GetPool(r))next.ServeHTTP(w, r.WithContext(ctx))})}
Как отвечать на собеседовании
Начните с прямого ответа: один кластер с синхронной репликацией в регионе, read-only реплики для глобального чтения. Затем объясните, почему это осознанный выбор: требования к консистентности, сложность мульти-мастер, операционные затраты. Упомяните, что рассматривали геораспределённые СУБД, но не готовы платить за их сложность. Покажите, что понимаете trade-off: задержка записи против сложности разрешения конфликтов. Если интервьюер спрашивает про сценарий глобальной записи - предложите конкретные альтернативы (CockroachDB, YugabyteDB) и объясните, как бы вы мигрировали. Не уходите в абстракции, привязывайте ответ к конкретному стеку и требованиям.
Что проверяет интервьюер
Интервьюер проверяет:
- понимание trade-off между консистентностью и доступностью (CAP-теорема на практике)
- способность обосновать архитектурное решение, а не просто назвать модный инструмент
- знание конкретных механизмов: синхронная репликация, quorum, read replicas, лаг репликации
- умение говорить о компромиссах без идеализации
- практический опыт: как вы решаете проблему задержек, как маршрутизируете запросы, как мониторите
Если вы говорите "мы используем один кластер" без объяснения, почему - это красный флаг. Если говорите "геораспределённая система" без упоминания конфликтов - тоже.
Типичные ошибки
- Утверждение, что геораспределённая система - всегда лучше, без учёта требований к консистентности
- Игнорирование лага репликации при использовании read replicas - это частая причина багов
- Ответ "мы используем один кластер, потому что так проще" без объяснения trade-off
- Путаница между синхронной и асинхронной репликацией, непонимание quorum commit
- Отсутствие конкретики: не упомянуть, как маршрутизируются запросы, как обрабатываются сбои
- Предложение мульти-мастер без обсуждения разрешения конфликтов (last-write-wins, CRDT, векторные часы)
> Похожие задачи по Go
Как отправляются события об изменении статусов?
Как хранится история переходов статусов платежей?
Как исправлять застрявшие платежи вручную при наличии реконсайл-джобы
Как следить за работой оркестратора и какие метрики использовать для проверки корректности
> Похожие задачи по backend
Как отправляются события об изменении статусов?
Как хранится история переходов статусов платежей?
Как исправлять застрявшие платежи вручную при наличии реконсайл-джобы
Как следить за работой оркестратора и какие метрики использовать для проверки корректности
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью