Ответ
Шардирование данных в Go можно реализовать несколькими способами:
- Range-based: данные распределяются по диапазонам ключей (например, пользователи A-M в шард 1, N-Z в шард 2)
func getShard(key string, totalShards int) int {
firstChar := strings.ToLower(key)[0]
return int(firstChar-'a') % totalShards
}
- Hash-based: хешируем ключ и берем модуль от количества шардов
func hashShard(key string, totalShards int) int {
h := fnv.New32a()
h.Write([]byte(key))
return int(h.Sum32()) % totalShards
}
- Directory-based: используем внешнюю lookup-таблицу для маппинга
Основные нюансы:
- Неравномерное распределение (hot shards)
- Решардинг при добавлении/удалении нод
- Транзакции между шардами
- Локализация связанных данных
Для production лучше использовать готовые решения типа Vitess, CockroachDB или YugabyteDB.