Как ответить
Шардирование — это разбиение одной логической базы данных на несколько физических узлов (шардов), каждый из которых хранит свою часть данных. Цель — горизонтальное масштабирование: распределить нагрузку на запись/чтение и не упираться в лимиты одной машины. В отличие от партиционирования (разделение таблиц внутри одного инстанса), шарды работают независимо — это отдельные серверы или кластеры.
Ключевой элемент шардирования — ключ шардирования (shard key). По его значению решается, в какой шард попадёт запись. Самые частые стратегии:
- Хеш-шардирование — берём хеш от ключа (например, user_id) и по модулю количества шардов определяем узел. Обеспечивает равномерное распределение, но добавление/удаление шардов требует решардинга.
- Диапазонное (range-based) — каждой шарде назначается диапазон значений (например, user_id от 1 до 1 000 000 — на шард A, от 1 000 001 до 2 000 000 — на B). Просто для реализации, но ведёт к неравномерной нагрузке (hot spots), если данные приходят скопом.
- Географическое / кастомное — по региону или типу клиента. Часто используется в мультитенантных системах.
Пример для простейшей реализации с хешем на PostgreSQL (с помощью pg_partman или внешнего роутера):
-- функция определения шарда по id пользователя
CREATE OR REPLACE FUNCTION get_shard(user_id INT) RETURNS INT AS $$
BEGIN
RETURN (user_id % 4) + 1; -- 4 шарда
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- при вставке вызов в коде:
INSERT INTO shard_1.users (id, name) VALUES ($1, $2) WHERE get_shard($1) = 1;
INSERT INTO shard_2.users (id, name) VALUES ($1, $2) WHERE get_shard($1) = 2;
-- …На практике такие схемы редко пишут руками — используют промежуточные слои (ProxySQL, Vitess, MongoDB Sharding, Citus для PostgreSQL), которые прозрачно роутерят запросы.
Основные проблемы шардирования:
- Cross-shard join'ы — если нужно соединить данные с разных шардов, приходится либо фетчить всё в приложение, либо использовать распределённые запросы (замедляется).
- Транзакции через шарды — стандартная consistency обходится дорого (2PC, Saga). Часто такие сценарии стараются локализовать в одном шарде.
- Решардинг — при изменении числа шардов нужно перераспределять данные. Это большая операция, обычно делают zero-downtime через виртуальные шарды (logical shards) и фоновую миграцию.
- Глобальные индексы и уникальность — ключ на всю таблицу (например, email) сложно поддерживать: каждую вставку надо проверять во всех шардах.
Когда применяется: соцсети (Facebook, Twitter — данные пользователей на разных узлах), SaaS-платформы (арендаторы живут в разных шардах), системы реального времени с большим трафиком записи. Для небольших проектов (до 10–20 млн записей, 500–1000 rps) шардирование обычно избыточно — сначала решают с помощью репликации, кэширования и индексов.