Какую проблему проектирования баз данных решает шардинг (Sharding)?

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

Ответ

Шардинг (горизонтальное партиционирование) решает проблему масштабирования базы данных при экстремальных объемах данных и высокой нагрузке на запись/чтение. Он распределяет строки одной логической таблицы по нескольким физическим базам данных (шардам), часто на разных серверах.

Проблемы, которые он решает:

  • Масштабирование записи: Традиционная репликация (master-slave) масштабирует только чтение. Шардинг позволяет распределить нагрузку на запись.
  • Размер базы данных: Позволяет хранить объем данных, превышающий возможности одного диска или сервера.
  • Производительность: Уменьшает размер индексов в каждом шарде и позволяет хранить данные географически ближе к пользователям.

Пример логики шардирования по ключу пользователя:

// Определение шарда на основе userId
public Shard determineShard(long userId) {
    int totalShards = 4;
    int shardId = (int) (userId % totalShards);
    return shardPool.getShard(shardId);
}

Преимущества:

  • Горизонтальное масштабирование (добавление новых шардов).
  • Повышенная отказоустойчивость (выход одного шарда не останавливает всю систему).

Недостатки и сложности:

  • Сложные JOIN: Объединение данных из разных шардов неэффективно и обычно выполняется на уровне приложения.
  • Распределенные транзакции: Требуют сложных протоколов (например, 2PC — two-phase commit).
  • Ребалансировка: Добавление новых шардов требует перемещения данных и изменения логики роутинга.
  • Нет глобальной уникальности: Сложно поддерживать последовательные ID (например, автоинкремент) across shards.