Ответ
Шардинг (горизонтальное партиционирование) решает проблему масштабирования базы данных при экстремальных объемах данных и высокой нагрузке на запись/чтение. Он распределяет строки одной логической таблицы по нескольким физическим базам данных (шардам), часто на разных серверах.
Проблемы, которые он решает:
- Масштабирование записи: Традиционная репликация (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.