Репликация и шардинг

Два разных ответа на два разных вопроса — и почему шардинг должен быть последним ходом, а не первым.

Два разных вопроса

Репликация отвечает на вопрос «что, если сервер базы умрёт, и как обслужить больше чтения». Шардинг — на вопрос «что делать, когда данные и запись перестали помещаться на один сервер». Их постоянно смешивают, но это независимые механизмы, и нужны они в разные моменты жизни системы.

Репликация

Primary принимает запись, реплики получают поток изменений (WAL) и обслуживают чтение.

Две вещи, которые кусают на практике:

  1. Lag. Реплика отстаёт на секунды. Сценарий «записал → тут же прочитал с реплики → данных нет» выглядит как баг приложения. Критичные чтения после записи направляют на primary.
  2. Failover не бесплатен. Автоматическое повышение реплики до primary — это отдельный инструмент (Patroni и подобные), правильные таймауты и репетиции. Ручной failover в 4 утра без процедуры — источник историй про потерянные данные.

Шардинг

Данные режутся по ключу шардирования (обычно id пользователя/тенанта), и каждый шард — самостоятельная база со своей частью данных. Запись масштабируется горизонтально — это единственная причина идти на такую цену:

Порядок ходов

Шардинг — последний ход, потому что он необратимо усложняет всё приложение. До него:

  1. индексы и запросы (чаще всего «база не тянет» — это один плохой запрос);
  2. вертикальный рост — железо всё ещё дешевле переписывания приложения;
  3. реплики на чтение;
  4. кеш перед базой;
  5. партиционирование больших таблиц внутри одной базы;
  6. и только затем — шардинг.

На собеседовании «как отмасштабировать базу?» проверяют именно порядок: кандидат, начинающий с шардинга, не платил за него ни разу.