Как распределить данные между базами при шардировании

«Как распределить данные между базами при шардировании» — вопрос из категории Базы данных, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Шардирование данных в Go можно реализовать несколькими способами:

  1. 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
}
  1. Hash-based: хешируем ключ и берем модуль от количества шардов
func hashShard(key string, totalShards int) int {
    h := fnv.New32a()
    h.Write([]byte(key))
    return int(h.Sum32()) % totalShards
}
  1. Directory-based: используем внешнюю lookup-таблицу для маппинга

Основные нюансы:

  • Неравномерное распределение (hot shards)
  • Решардинг при добавлении/удалении нод
  • Транзакции между шардами
  • Локализация связанных данных

Для production лучше использовать готовые решения типа Vitess, CockroachDB или YugabyteDB.