Для чего лучше подходят синхронные и асинхронные репликации
Что проверяют
Понимаете ли вы, что режим репликации это компромисс между потерей данных, задержкой записи и доступностью. Следом обычно спрашивают, что будет с записью, если синхронная реплика упала, и можно ли читать с реплики свежие данные сразу после коммита.
Как отвечать
- асинхронная: мастер подтверждает коммит, не дожидаясь реплик. Запись быстрая, падение реплики мастер не замечает, но при аварии мастера теряется всё, что не успело доехать, то есть RPO больше нуля. Режим по умолчанию в PostgreSQL и MySQL;
- синхронная: коммит подтверждается после ответа реплики. Подтверждённая транзакция переживает потерю мастера, но каждая запись платит сетевой круг до реплики, а между регионами это десятки миллисекунд;
- полусинхронная (semi-sync в MySQL): мастер ждёт, что реплика получила событие и записала его в relay log, но не применила.
В PostgreSQL глубину ожидания задаёт synchronous_commit: remote_write, on (WAL сброшен на диск реплики), remote_apply (транзакция уже видна на реплике). Реплики перечисляют в synchronous_standby_names, в том числе кворумом: ANY 1 (s1, s2). Отставание видно в pg_stat_replication: write_lag, flush_lag, replay_lag.
Синхронная подходит для платежей, балансов и заказов, где потеря подтверждённой записи недопустима, и для реплик в той же или соседней зоне доступности. Асинхронная для реплик чтения и отчётов, DR-копии в другом регионе, аналитики. На практике их совмещают: две реплики рядом с кворумом ANY 1 и асинхронная далеко. В Patroni это включается через synchronous_mode.
Та же логика в Kafka: acks=all плюс min.insync.replicas.
Где спотыкаются
Считают, что при падении единственной синхронной реплики мастер продолжит писать. В PostgreSQL коммиты просто повиснут, поэтому нужны две реплики и кворум.
Путают репликацию с бэкапом: ошибочный DROP TABLE уедет на реплику так же быстро, как нужная запись.
Уверены, что при синхронной репликации чтение с реплики всегда свежее. С synchronous_commit = on это не так, видимость гарантирует только remote_apply.