Ответ
Шардирование (горизонтальное партиционирование) — это метод распределения данных одной логической базы данных между несколькими серверами (шардами). Каждый шард содержит подмножество данных и работает как независимая база.
Зачем это нужно:
- Масштабирование записи и чтения: Нагрузка распределяется между узлами.
- Увеличение доступности: Отказ одного шарда не приводит к падению всей системы.
- Географическое распределение: Данные можно размещать ближе к пользователям.
Ключевые концепции:
- Ключ шардирования: Определяет, на какой шард попадут данные (например,
user_id,tenant_id). - Стратегии шардирования:
- Диапазонное: Данные распределяются по диапазонам ключа (например, A-M на шард 1, N-Z на шард 2). Может привести к дисбалансу ("горячие" шарды).
- Хэш-шардирование: Ключ хэшируется, и хэш определяет шард. Обеспечивает равномерное распределение, но усложняет запросы по диапазонам.
- Шардирование по справочнику: Используется отдельная lookup-таблица для сопоставления ключа и шарда. Гибко, но требует поддержки отдельного сервиса.
Проблемы и решения:
- Запросы, затрагивающие несколько шардов (fan-out): Требуют агрегации результатов от всех шардов, что медленно. Решение — дублирование данных или использование материализованных представлений.
- Решардинг (перераспределение данных): Необходим при добавлении/удалении шардов. Сложная операция, требующая миграции данных без простоя. Современные системы (например, Vitess, CockroachDB) делают это прозрачно.
- Транзакции, затрагивающие несколько шардов: Реализуются через протоколы распределенного консенсуса (например, 2PC, Raft), что влияет на производительность.
Пример (концептуальный): База пользователей шардирована по user_id на 3 узла с использованием хэша.
-- Определение шарда для пользователя с id=123
shard_index = hash(123) % 3 -- Например, результат = 1
-- Запрос направляется на шард 1
SELECT * FROM users WHERE user_id = 123 ON shard_1;