Репликация: master-replica, синхронная и асинхронная, read replicas
↑ 6.1 Масштабирование и надёжность данных · → Следующая
Зачем это на собесе
Репликация — база отказоустойчивости и масштабирования чтения. Спрашивают виды, задержку и проблемы согласованности.
Зачем
- отказоустойчивость: при падении основного узла есть копия (failover);
- масштабирование чтения: запросы разносятся на реплики;
- изоляция нагрузок: отчёты и бэкапы на реплике;
- территориальная близость и DR (реплика в другом регионе).
Репликация не заменяет бэкапы: удаление или порча данных реплицируются мгновенно.
Виды
| Физическая (streaming) | Логическая | |
|---|---|---|
| Что передаёт | изменения WAL на уровне блоков | изменения строк (INSERT/UPDATE/DELETE) |
| Реплика | точная копия всего кластера, read-only (hot standby) | любая схема, выборочные таблицы, другая версия БД |
| Применение | HA, read replicas | миграции версий, CDC, интеграции, частичная репликация |
| Ограничения | одинаковая major-версия, вся БД | нужен PK/REPLICA IDENTITY, DDL не передаётся, последовательности вручную |
PostgreSQL: физическая pg_basebackup + primary_conninfo; логическая — CREATE PUBLICATION / CREATE SUBSCRIPTION.
-- на основном (логическая)
CREATE PUBLICATION pub_orders FOR TABLE orders, order_items;
-- на подписчике
CREATE SUBSCRIPTION sub_orders CONNECTION 'host=pg1 dbname=app user=repl' PUBLICATION pub_orders;Синхронная и асинхронная
| Асинхронная | Синхронная | |
|---|---|---|
| Подтверждение коммита | после записи на основном | после подтверждения реплики(ами) |
| Задержка записи | минимальная | выше (RTT до реплики) |
| Потеря данных при сбое | возможна (RPO > 0) | нет (RPO = 0) при сохранности реплики |
| Доступность записи | не зависит от реплик | падает, если нет синхронной реплики |
PostgreSQL: synchronous_standby_names = 'FIRST 1 (replica1, replica2)' или ANY 1 (...) (кворум), synchronous_commit (on, remote_write, remote_apply, local, off). Компромисс: кворумная синхронность (ANY 1 из 2) балансирует надёжность и доступность.
Лаг репликации и read-your-writes
Асинхронные реплики отстают (миллисекунды–секунды, под нагрузкой — минуты). Последствия: пользователь изменил данные и не видит их при чтении с реплики.
Решения:
- читать только с основного после записи (на время сессии/запроса) — «sticky»;
- отслеживать LSN: клиент запоминает позицию записи, реплика отдаёт данные, если
pg_last_wal_replay_lsn() >= lsn; synchronous_commit = remote_applyдля критичных операций;- маршрутизация: критичное чтение — на primary, отчёты — на реплику;
- мониторинг лага:
pg_stat_replication(write_lag,flush_lag,replay_lag),pg_last_xact_replay_timestamp().
Конфликты на реплике (recovery conflicts): долгие запросы на реплике конфликтуют с применением WAL (max_standby_streaming_delay, hot_standby_feedback — но он раздувает основной).
Топологии
- один primary + N реплик (цепочки/каскад: реплика питает другие реплики);
- multi-master (BDR, Citus, Galera-подобные): конфликты записи, сложность;
- Active-passive (резерв) и active-active (запись в нескольких регионах, нужны разрешение конфликтов и идемпотентность).
Failover и promote
- ручной:
pg_ctl promote/SELECT pg_promote(); - автоматический: Patroni (etcd/Consul/ZooKeeper как DCS), repmgr, pg_auto_failover, облачные (RDS Multi-AZ, Cloud SQL HA);
- задачи: выбор наиболее актуальной реплики, fencing старого основного (защита от split-brain), обновление адресов (VIP, DNS, HAProxy/PgBouncer), перевод остальных реплик на нового лидера (
pg_rewind); - учения: регулярные тесты переключения.
В приложении
- строка подключения к primary (через HAProxy/PgBouncer/VIP) и отдельная к реплике для чтения; в Npgsql
Target Session Attributes=primary / prefer-standby, мульти-хост строки подключения; - учёт ошибок при failover: повторы идемпотентных операций, короткие retry,
transient fault handling; - EF Core: два
DbContext(чтение/запись) или перехватчик маршрутизации.
Другие БД
| Система | Репликация |
|---|---|
| MySQL | binlog (асинхронная, полусинхронная, Group Replication) |
| MongoDB | replica set, выборы, writeConcern: majority |
| Redis | асинхронная + Sentinel/Cluster |
| ClickHouse | ReplicatedMergeTree через Keeper (мультимастер) |
| Kafka | ISR-реплики партиций |
| Cassandra | leaderless, настраиваемый кворум |
Вопросы с ответами
Чем синхронная репликация отличается от асинхронной?
Синхронная ждёт подтверждения реплики перед коммитом (нет потери данных, выше задержка, зависимость от реплики); асинхронная не ждёт (быстрее, но при сбое можно потерять последние транзакции).
Заменяет ли репликация бэкапы?
Нет. Ошибочное удаление или повреждение данных мгновенно реплицируется. Нужны бэкапы и PITR.
Как решить проблему read-your-writes при чтении с реплик?
Читать с primary после записи в рамках сессии, использовать ожидание нужного LSN на реплике, синхронную репликацию для критичных операций или направлять чувствительные запросы на primary.