> Вы используете один кластер или геораспределенную систему? (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 мс). Это приемлемо для наших сценариев - операции записи редкие и не критичны к задержке. Для чтения - локальная реплика, задержка минимальна.

Пример кода

GO
type DBSelector struct {
primary *pgxpool.Pool
replicas []*pgxpool.Pool
rr 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
}
// middleware
func 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, векторные часы)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью