Ответ
Шардирование — это техника горизонтального масштабирования базы данных, при которой данные разделяются на независимые части (шарды) и распределяются по разным серверам.
Основные подходы:
1. Sharding по диапазону (Range-based)
- Описание: Данные делятся на основе диапазона значений ключа шарда (например, по алфавиту, дате, ID).
- Плюсы: Простота реализации, эффективность запросов по диапазону (например,
SELECT * FROM users WHERE name BETWEEN 'A' AND 'C'
). - Минусы: Риск появления "горячих точек" (hotspots), когда один шард получает непропорционально большую нагрузку (например, при регистрации новых пользователей ID будут попадать в последний диапазон).
// Пример: выбор шарда по первой букве имени
func getShardByRange(name string) int {
if len(name) == 0 { return 0 }
firstChar := strings.ToUpper(name[0:1])
if firstChar >= "A" && firstChar <= "M" {
return 0 // Шард 1
}
return 1 // Шард 2
}
2. Sharding по хешу (Hash-based)
- Описание: Шард определяется на основе хеш-функции от ключа (
shard_id = hash(key) % N
, где N — число шардов). - Плюсы: Обеспечивает более равномерное распределение данных по шардам.
- Минусы: Сложность решардинга. При добавлении нового шарда (изменении
N
) почти все ключи будут перераспределены. Запросы по диапазону становятся невозможными.
// Пример: выбор шарда по хешу от ключа
func getShardByHash(key string, totalShards int) int {
h := fnv.New32a()
h.Write([]byte(key))
return int(h.Sum32()) % totalShards
}
3. Согласованное хеширование (Consistent Hashing)
- Описание: Улучшенная версия хеш-шардинга. Ключи и серверы отображаются на одно и то же кольцевое пространство. Ключ сохраняется на первом сервере, который встречается при движении по часовой стрелке.
- Плюсы: Минимизирует перемещение данных при добавлении/удалении шардов (влияет только на соседние узлы).
- Минусы: Более сложная реализация. Возможно неравномерное распределение данных, что решается с помощью "виртуальных узлов".
4. Sharding на основе каталога (Directory-based)
- Описание: Используется отдельная таблица-справочник (lookup table), которая хранит соответствие ключа шардирования и физического местоположения шарда.
- Плюсы: Максимальная гибкость — можно легко перемещать данные между шардами, просто обновив запись в каталоге.
- Минусы: Каталог сам по себе является узким местом и потенциальной точкой отказа. Требуется дополнительный сетевой запрос для определения шарда.