За асинхронної реплікації репліка застосовує зміни з запізненням - зазвичай мілісекунди, але під навантаженням, при великих транзакціях чи проблемах мережі це можуть бути секунди й хвилини.
Що бачить користувач:
- Створив замовлення, його перенаправили на сторінку замовлення - а там «не знайдено», бо читання пішло на репліку, куди запис ще не дійшов.
- Змінив пароль чи налаштування - а сторінка показує старе значення.
- Воркер черги отримує завдання з ID щойно створеного запису, читає з репліки - і не знаходить його.
Як з цим жити:
- Читати свої записи з primary. У Laravel - опція
sticky => true: після запису в межах того самого запиту всі читання йдуть на primary. - Критичні читання - завжди з primary: перевірка балансу перед списанням, авторизація, все, що веде до запису.
- Передавати дані, а не лише ID, або відкладати завдання черги до коміту (
afterCommit) і читати їх з primary. - Моніторити затримку і прибирати відсталу репліку з ротації читання. У PostgreSQL -
pg_stat_replicationна primary таnow() - pg_last_xact_replay_timestamp()на репліці.
Синхронна реплікація прибирає затримку для підтверджених транзакцій, але кожен COMMIT чекає репліку - запис повільніший, а падіння репліки може зупинити запис на primary. Тому її вмикають свідомо, для даних, втрата яких неприпустима.