Шардирование
Шардирование — разрезание одной базы данных на части (шарды), которые живут на разных серверах и вместе образуют полный набор данных.
Что такое шардирование
Шардирование (sharding, шардинг) — разделение одной логической базы данных на части, размещённые на разных серверах. Каждая такая часть называется шардом и содержит свой кусок данных; вместе шарды составляют полный набор.
Шард — это не копия, а фрагмент. Пользователи с id от 1 до 1 000 000 лежат на шарде 1, от 1 000 001 до 2 000 000 — на шарде 2. Ни на одном сервере нет всех данных, и в этом смысл: снимается ограничение одной машины по объёму диска, памяти и скорости записи.
Слово происходит от английского shard — осколок, черепок.
Шардирование, репликация и партиционирование
Три понятия, которые постоянно смешивают:
| Что делает | Что решает | |
|---|---|---|
| Репликация | Копирует все данные на другие серверы | Отказоустойчивость, масштаб чтения |
| Партиционирование | Режет таблицу на части внутри одного сервера | Управляемость, скорость сканов |
| Шардирование | Режет данные между разными серверами | Масштаб записи и объёма |
Репликация и шардирование не конкурируют, а дополняют друг друга: в боевой системе каждый шард имеет свои реплики, иначе отказ одного сервера отнимает часть данных целиком.
Партиционирование — то, что стоит попробовать раньше шардирования. В PostgreSQL декларативные партиции по дате решают большинство задач с большими таблицами, не вводя распределённой системы:
CREATE TABLE events (id bigserial, ts timestamptz, payload jsonb)
PARTITION BY RANGE (ts);
CREATE TABLE events_2026_07 PARTITION OF events
FOR VALUES FROM ('2026-07-01') TO ('2026-08-01');
Ключ шардирования
Shard key — колонка, по значению которой определяется шард строки. Это единственное по-настоящему важное решение, и оно почти необратимо: смена ключа означает перераспределение всех данных.
| Стратегия | Как работает | Плюсы | Минусы |
|---|---|---|---|
| По диапазону | id 1–1M → шард 1 |
Простая, range-запросы работают | Перекос: новые данные все в последний шард |
| По хешу | hash(user_id) % N |
Равномерное распределение | Range-запросы идут во все шарды |
| По справочнику | Таблица соответствий | Гибко, можно двигать точечно | Справочник — узкое место |
| Географически | По региону клиента | Данные близко к пользователю, 152-ФЗ | Неравномерность регионов |
Хороший ключ обладает тремя свойствами: высокая кардинальность, равномерность распределения и присутствие в большинстве запросов. Классические ошибки — шардировать по дате создания (вся запись валится в последний шард, остальные простаивают) или по полю с малым числом значений вроде status.
Отдельная беда — hot shard: один крупный клиент генерирует больше нагрузки, чем весь остальной шард. Поэтому шардирование по tenant_id в мультитенантной системе требует плана на случай, когда один арендатор перерастёт машину.
Проблема % N
Наивная схема hash(key) % 4 ломается при добавлении пятого сервера: % 5 даёт другой остаток почти для всех ключей, и переезжать должны почти все данные. Решения — консистентное хеширование (при добавлении узла двигается ~1/N данных) либо виртуальные шарды: сразу нарезать данные на 1024 логических шарда и раскладывать их по физическим серверам пачками. Второе проще и потому распространено: рост кластера превращается в перенос части виртуальных шардов.
Что ломается после шардирования
Цена решения — приложение перестаёт работать с базой как с единым целым:
JOINмежду шардами. Соединить таблицы, лежащие на разных серверах, штатным SQL нельзя. Данные либо денормализуют, либо собирают в коде.- Транзакции. ACID в пределах шарда — да; через несколько шардов — только двухфазный коммит со всеми его издержками.
- Уникальность.
AUTO_INCREMENTнезависим на каждом шарде. Нужны UUID или генератор вроде Snowflake. - Агрегаты.
COUNT,SUM,ORDER BY ... LIMITпо всей базе — это запрос во все шарды и сборка результата. - Схема. Миграции надо накатить на каждый шард и пережить состояние, когда часть шардов уже обновлена, а часть ещё нет.
- Эксплуатация. Бэкапы, мониторинг и восстановление — теперь для N серверов, причём консистентно между ними.
Когда шардировать
Шардирование — последнее средство, а не первое. Сначала честно проходят более дешёвые шаги: индексы и оптимизация запросов, вертикальный рост сервера, кеш перед базой, вынос чтения на реплики, партиционирование, вынос аналитики в ClickHouse. Каждый из них проще эксплуатировать, чем распределённую базу.
Реальные поводы: объём данных не влезает на самый большой доступный сервер; поток записи упирается в один узел (реплики тут не спасают — пишем всё равно в primary); требования по географии.
Готовые решения
- MongoDB — sharded cluster встроен, распределением занимается
mongos. - Citus — расширение PostgreSQL, превращающее его в распределённую БД.
- Vitess — шардирование MySQL, выросшее из YouTube.
- Redis Cluster — 16384 хеш-слота между узлами.
- ClickHouse — распределённые таблицы поверх шардов.
Использовать готовое почти всегда разумнее, чем писать роутинг по шардам в приложении: логика выбора шарда, ребалансировка и отказоустойчивость там уже продуманы.
Связанные термины
- Репликация — копирование данных вместо разрезания
- Базы данных — что именно шардируют
- MongoDB — встроенный sharded cluster
- PostgreSQL — партиционирование и Citus
- Кластер — группа серверов, между которыми делят данные
- Индексы в БД — что пробуют до шардирования
Готовы запустить GPU-задачу?
Запустить GPU-сервер