В чем разница между шардированием и репликацией в базах данных?

«В чем разница между шардированием и репликацией в базах данных?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Шардирование (горизонтальное партиционирование) и репликация — это две ключевые техники масштабирования баз данных, решающие разные проблемы.

Репликация

  • Цель: Повышение доступности (availability) и отказоустойчивости (fault tolerance), а также распределение нагрузки на чтение.
  • Как работает: Создаются точные копии (реплики) набора данных на нескольких серверах.
  • Модели:
    • Master-Slave (Источник-Реplica): Запись только в мастер, чтение из мастер и реплик.
    • Multi-Master: Запись в любой узел, с последующей синхронизацией между всеми.
  • Преимущества: Отказоустойчивость (при падении мастера реплика становится новой мастер), географическое распределение, снижение нагрузки на мастер за счет чтения с реплик.
  • Недостатки: Не решает проблему масштабирования записи, возможна задержка репликации (несогласованность данных).

Концептуальный пример:

-- Все узлы содержат ОДИН И ТОТ ЖЕ набор данных
-- Мастер-узел для записи
MASTER: INSERT INTO users (id, name) VALUES (1, 'Alice');
-- Реплики для чтения (данные появятся после синхронизации)
REPLICA_1: SELECT * FROM users; --> Возвращает Alice
REPLICA_2: SELECT * FROM users; --> Возвращает Alice

Шардирование

  • Цель: Горизонтальное масштабирование (scaling out) для обработки больших объемов данных и высокой нагрузки на запись.
  • Как работает: Набор данных разделяется (партиционируется) на меньшие части (шарды) по определенному ключу (например, user_id), и каждый шард размещается на отдельном сервере.
  • Стратегии: По диапазону, по хешу, по списку.
  • Преимущества: Масштабирование и записи, и чтения; работа с объемами данных, превышающими возможности одного сервера.
  • Недостатки: Сложность: операции JOIN и транзакции, затрагивающие несколько шардов, становятся нетривиальными; неравномерное распределение нагрузки ("горячие" шарды).

Концептуальный пример (шардирование по user_id % 3):

-- Данные РАЗДЕЛЕНЫ между разными серверами
SHARD_0 (user_id % 3 = 0): SELECT * FROM users WHERE id = 3; --> Возвращает пользователя 3
SHARD_1 (user_id % 3 = 1): SELECT * FROM users WHERE id = 1; --> Возвращает пользователя 1
SHARD_2 (user_id % 3 = 2): SELECT * FROM users WHERE id = 2; --> Возвращает пользователя 2
-- Запрос, требующий данных со всех шардов, сложен:
-- SELECT * FROM users ORDER BY created_at; -- Нужно запрашивать все шарды и объединять

Сравнительная таблица

Аспект Репликация Шардирование
Основная цель Надежность и доступность Масштабируемость (производительность)
Структура данных Одинаковые данные на каждом узле Разные данные на каждом узле
Масштабирование записи Нет (запись обычно в один мастер) Да (запись распределяется по шардам)
Масштабирование чтения Да (чтение с реплик) Да (чтение распределяется по шардам)
Сложность запросов Низкая (данные локальны) Высокая (межшардовые JOIN, агрегации)
Отказоустойчивость Высокая (данные дублируются) Зависит от реализации (потеря шарда = потеря части данных)

Практическое применение

На практике эти техники часто комбинируются. Например:

  1. Сначала применяется шардирование для разделения данных.
  2. Затем каждый шард реплицируется (например, в конфигурации мастер-реплика) для обеспечения отказоустойчивости внутри шарда.

Таким образом, система получает преимущества обоих подходов: горизонтальную масштабируемость от шардирования и высокую доступность от репликации.