> Работали ли вы с репликацией таблиц (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Сбер

Стек: Go

> Пример ответа

Короткий ответ

Да, работал с репликацией таблиц в PostgreSQL и ClickHouse на продакшене. Настраивал физическую репликацию через streaming replication, логическую через logical decoding, а также использовал managed-решения вроде AWS RDS Multi-AZ. Основной фокус - обеспечение консистентности, мониторинг лага репликации и обработка конфликтов при записи в реплики.

Подробное объяснение

Репликация таблиц - это процесс копирования данных с primary-ноды на реплики для обеспечения отказоустойчивости, горизонтального масштабирования чтения и аналитических нагрузок. В PostgreSQL есть два основных подхода:

Физическая репликация - копирует WAL-журнал на уровне байтов. Реплика идентична primary, поддерживает горячий standby для чтения. Ограничение - нельзя реплицировать отдельные таблицы, только всю базу целиком.

Логическая репликация - использует logical decoding, позволяет реплицировать отдельные таблицы, поддерживает разные версии PostgreSQL на primary и реплике, а также фильтрацию по строкам и колонкам. Это ключевой механизм для event-driven архитектур и CDC (change data capture).

В ClickHouse репликация работает через ZooKeeper/ClickHouse Keeper: каждая реплика таблицы - это отдельная нода, а синхронизация идёт через shared log. Репликация асинхронная, но консистентность в пределах партиций гарантируется.

Ключевые trade-off:

  • синхронная vs асинхронная репликация - задержка против гарантий durability
  • физическая vs логическая - простота против гибкости
  • репликация всей базы vs отдельных таблиц - операционная сложность

На практике

В Go-проектах чаще всего сталкиваешься с репликацией на уровне инфраструктуры, а не кода. Но важно понимать, как поведёт себя приложение при чтении с реплик: лаг репликации может дать устаревшие данные. Поэтому в коде обычно:

  • разделяешь read/write пулы соединений
  • для критичных данных используешь session_replication_role или читаешь с primary
  • настраиваешь max_standby_streaming_delay и мониторишь pg_stat_replication

Для логической репликации в Go часто используют библиотеки вроде jackc/pglogrepl для написания собственного CDC-консьюмера, либо готовые решения типа Debezium + Kafka.

Пример кода

GO
// Разделение чтения и записи при работе с репликами PostgreSQL
type DB struct {
primary *sql.DB
replica *sql.DB
}
func (db *DB) GetUser(ctx context.Context, id int, allowStale bool) (*User, error) {
// Для критичных данных всегда читаем с primary
if !allowStale {
return queryUser(ctx, db.primary, id)
}
// Для некритичных - с реплики, но проверяем лаг
var lag time.Duration
err := db.replica.QueryRowContext(ctx,
"SELECT now() - pg_last_xact_replay_timestamp()").Scan(&lag)
if err != nil || lag > 5*time.Second {
return queryUser(ctx, db.primary, id)
}
return queryUser(ctx, db.replica, id)
}
// Мониторинг лага репликации
func CheckReplicationLag(ctx context.Context, db *sql.DB) error {
rows, err := db.QueryContext(ctx, `
SELECT client_addr, state,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes
FROM pg_stat_replication`)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var addr string
var state string
var lag int64
if err := rows.Scan(&addr, &state, &lag); err != nil {
return err
}
log.Printf("replica %s state=%s lag=%d bytes", addr, state, lag)
}
return rows.Err()
}

Как отвечать на собеседовании

Начни с конкретики: назови системы, с которыми реально работал. Затем покажи понимание различий между физической и логической репликацией. Обязательно упомяни проблемы, с которыми сталкивался: лаг репликации, конфликты при логической репликации, поведение при network partition. Если есть опыт с CDC - это сильный плюс, расскажи как использовал это для синхронизации с поисковым индексом или аналитическим хранилищем. Не уходи в абстрактные рассуждения, приводи конкретные сценарии из продакшена.

Что проверяет интервьюер

Интервьюер проверяет:

  • понимание фундаментальных механизмов репликации, а не только умение настроить через GUI
  • способность проектировать систему с учётом консистентности и доступности (CAP)
  • знание operational-аспектов: мониторинг, алерты, failover
  • умение принимать trade-off решения: когда логическая репликация оправдана, а когда физическая достаточна
  • практический опыт с конкретными СУБД, а не только теорию

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

  • Путаница между физической и логической репликацией, непонимание, что логическая работает на уровне строк, а не WAL
  • Утверждение, что реплики всегда консистентны - забывают про асинхронность и лаг
  • Игнорирование конфликтов при логической репликации: одинаковые primary keys на разных нодах
  • Отсутствие стратегии мониторинга лага - без этого репликация бесполезна
  • Попытка использовать реплику для записи без понимания ограничений (read-only режим)
  • Незнание, как ведёт себя приложение при недоступности реплики - нет fallback на primary

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

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