Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як репліки бази для читання допомагають масштабуватися і чим небезпечна затримка реплікації?

У більшості вебзастосунків читань у десятки разів більше, ніж записів. Репліки дають змогу розподілити читання між кількома серверами бази, а всі записи лишити на основному (primary).

У Laravel - розділення з'єднань:

'mysql' => [
    'read' => ['host' => ['10.0.0.11', '10.0.0.12']],
    'write' => ['host' => ['10.0.0.10']],
    'sticky' => true,
    // ...
],

SELECT ідуть на репліки, усе інше - на основний сервер.

Затримка реплікації - репліка отримує зміни з запізненням: зазвичай мілісекунди, під навантаженням чи при важких запитах - секунди й більше.

Типові наслідки:

  • «не бачу свого запису»: користувач зберіг профіль, сторінка після редиректу читає з репліки - і показує старі дані;
  • джоба в черзі не знаходить запис: модель щойно створено на основному сервері, воркер читає з репліки, де її ще немає, - ModelNotFoundException;
  • неправильні рішення: перевірка «чи вистачає залишку на складі» на застарілій репліці.

Як з цим жити:

  • sticky => true - якщо в поточному запиті був запис, наступні читання цього ж запиту йдуть на основний сервер;
  • читання з основного сервера там, де важлива свіжість: після запису, при перевірках перед зміною даних, у критичних джобах (->useWritePdo(), окреме з'єднання);
  • «читати свої записи» - кілька секунд після запису користувача направляти його читання на основний сервер (позначка в сесії);
  • моніторинг затримки реплікації зі сповіщеннями - і автоматичне виключення відсталої репліки з пулу.

Що репліки не вирішують:

  • масштабування записів - усі записи все одно на одному сервері;
  • повільні запити - запит, що займає 10 секунд, займе їх і на репліці. Спершу індекси й оптимізація.

Корисне застосування окремої репліки: важкі звіти, аналітика, бекапи - щоб вони не впливали на основний трафік.

Докладніше в документації: Laravel: з'єднання для читання й запису

Схожі питання