Шардирование базы данных: когда оно нужно и как выбрать схему
Шардирование распределяет данные между несколькими серверами, но вместе с нагрузкой распределяет и сложность: запросы, транзакции и миграции становятся труднее. Разбираем, как понять, что пора делить базу, и выбрать способ без преждевременной перестройки.

Когда одна база перестаёт укладываться в требования по объёму или нагрузке, добавить ещё один сервер — не всегда решение: без маршрутизации запросов он не возьмёт на себя часть данных. Шардирование может помочь, но усложнит транзакции, аналитику и эксплуатацию. Ниже — как оценить необходимость и выбрать подход для PostgreSQL 16, не путая разделение таблиц с распределением по серверам.
Сначала найдите узкое место
Шардирование имеет смысл, когда вы понимаете, что именно упирается в предел: место на диске, пропускная способность записи, число соединений или задержка конкретных запросов. Если проблема в неудачном плане выполнения, отсутствии индекса или слишком широком запросе, разнос данных по серверам может лишь добавить сетевые задержки и новые точки отказа.
Перед архитектурными изменениями соберите базовые показатели:
- объём данных и скорость его роста, включая индексы;
- загрузку CPU, диска и сети на сервере базы во время пиков;
- задержки запросов и долю времени, которую занимают самые частые запросы;
- число соединений и ожиданий блокировок;
- долю операций, которым нужны данные из разных частей системы.
Сравнивайте периоды одинаковой нагрузки и учитывайте, что занимает место не только таблица, но и индексы, служебные данные и резервные копии. Если показатели говорят о проблеме с отдельными запросами, начните с их разбора. Если ресурсов не хватает всей базе, проверьте возможность вертикального масштабирования и удаления ненужных данных. Шардирование стоит рассматривать, когда эти меры не дают нужного результата или вы заранее знаете, что рост одной базы превысит доступные ресурсы.
Шардирование — не бесплатное ускорение. Вы меняете предел одной машины на обязанность приложения знать, где лежит каждая запись.
Не путайте шарды с секциями PostgreSQL
В PostgreSQL 16 есть декларативное секционирование: одна логическая таблица делится на секции по диапазону, списку или хешу значений. Это помогает организовать данные и, при подходящих запросах, не читать лишние секции. Но секции в обычной конфигурации находятся в том же кластере PostgreSQL: они не распределяют запись и хранение между несколькими независимыми серверами.
Секция — часть секционированной таблицы, которой управляет PostgreSQL. Шард — часть общего набора данных, размещённая на отдельном узле или сервере и выбранная по правилу маршрутизации. Секционирование может упростить работу с большими таблицами, но само по себе не превращает один сервер в распределённую базу.
Если нужны именно несколько серверов, вам потребуется либо маршрутизация в приложении, либо система распределённой базы данных. Внешние расширения для PostgreSQL тоже могут решать эту задачу, но совместимость и поддерживаемые возможности нужно проверять для конкретной версии расширения и PostgreSQL.
Три способа распределить данные
| Подход | Что выигрываете | За что платите |
|---|---|---|
| Секционирование в PostgreSQL 16 | Проще обслуживать крупную таблицу; запросы могут читать только нужные секции. | Данные остаются в одном кластере: это не горизонтальное масштабирование между серверами. |
| Шарды и маршрутизация в приложении | Вы сами выбираете правило распределения и можете масштабировать узлы по мере роста. | Приложению и связанным сервисам нужно правильно выбирать сервер; сложнее запросы, транзакции, перенос данных и эксплуатация. |
| Распределённая СУБД или расширение | Часть маршрутизации и распределённой работы берёт на себя платформа. | Появляется зависимость от её ограничений, версии и модели выполнения запросов; перенос с обычного PostgreSQL может потребовать изменений. |
Секционирование подходит, если нужно управлять частями большой таблицы, а ресурсов одного кластера пока достаточно. Приложение с собственными шардами имеет смысл, если команде нужны контроль над маршрутизацией и возможность независимо масштабировать узлы — и есть ресурсы поддерживать эту логику. Распределённую СУБД или расширение стоит выбирать, если её модель запросов соответствует системе и вы готовы принять ограничения конкретного продукта.
Выберите ключ, который совпадает с запросами
Ключ шарда определяет, на какой сервер попадёт запись. Хороший ключ помогает направить типичный запрос сразу на один шард. Например, если большинство операций в сервисе относятся к одному клиенту, идентификатор клиента может быть кандидатом. Это не универсальный рецепт: сначала проверьте реальные запросы и связи между сущностями.
Обычно выбирают один из двух вариантов:
- Хеширование ключа. Записи распределяются более равномерно, если значения ключа достаточно разнообразны. Но запросы по диапазону значений сложнее направлять на ограниченное число узлов, а при изменении числа шардов может понадобиться перераспределить данные.
- Диапазоны ключа. Удобно выбирать данные за период или по порядку ключа. Но если новые записи постоянно попадают в один край диапазона, нагрузка может сконцентрироваться на одном шарде. Границы диапазонов придётся контролировать.
До выбора ключа ответьте на четыре вопроса: какие запросы составляют основную нагрузку; есть ли у каждой записи однозначный ключ маршрутизации; как часто запросы затрагивают сразу несколько клиентов или шардов; можно ли переместить запись, если правило распределения изменится. Если приложение регулярно соединяет данные разных клиентов, проверьте, не станет ли почти каждый такой запрос распределённым.
Внедряйте постепенно, а не переключайте всё сразу
- Зафиксируйте исходные показатели. Запишите объём данных, задержки, частоту запросов и потребление ресурсов на пике. Проверка: вы можете повторить замер при сопоставимой нагрузке и понять, что именно должно улучшиться.
- Составьте карту запросов и связей. Отметьте, какие операции работают в пределах одного ключа, а какие читают или меняют данные разных групп. Проверка: у основных сценариев есть понятный ответ, сколько шардов они затрагивают.
- Проверьте правило на копии данных. Оцените распределение по выбранному ключу, неравномерность нагрузки и размер наиболее активных групп. Проверка: ни один очевидный сегмент не собирает непропорционально много записей или операций.
- Определите, как приложение узнаёт расположение данных. Способ маршрутизации должен быть одинаковым для чтения и записи, а правила — согласованными между сервисами. Проверка: запрос по тестовым ключам стабильно попадает на ожидаемый узел.
- Продумайте перенос и возврат. Опишите копирование данных, сверку результатов и действия при откате. Проверка: команда может выполнить пробный перенос на тестовой среде и обнаружить расхождения до переключения пользователей.
- Включайте новую схему поэтапно. Начните с ограниченного потока или группы данных и следите за задержками, ошибками и перекосом нагрузки. Проверка: новые показатели не ухудшились относительно исходных без объяснимой причины, а план возврата остаётся выполнимым.
Что ломается после разделения
Запросы между шардами. Если нужные строки лежат на разных узлах, системе приходится собирать результаты из нескольких мест. Это увеличивает количество сетевых обращений и может усложнить сортировку, агрегацию и соединения. До запуска посчитайте, как часто такой сценарий встречается в реальном трафике.
Транзакции и ограничения целостности. Операция, которая раньше меняла связанные записи в одной базе, может затронуть несколько серверов. Не рассчитывайте автоматически на те же гарантии и ограничения, что работали в одном кластере: проверьте, что именно поддерживает выбранная архитектура, и отдельно протестируйте сбои во время записи.
Перекос нагрузки. Равное число строк на шардах не означает равную нагрузку. Один крупный клиент или особенно активный ключ способен перегрузить сервер, хотя остальные будут простаивать. Следите одновременно за объёмом данных, интенсивностью запросов и ресурсами по каждому узлу.
Перемещение данных и отказы. При добавлении узла части данных может потребоваться перенести. Пока копия создаётся, важно понимать, как система обрабатывает новые записи и как проверяет согласованность. Также заранее решите, что увидит приложение, если один шард недоступен: какие операции остановятся, а какие можно безопасно повторить.
Отдельная тема — резервное копирование и восстановление распределённой системы: их план нужно проверять на выбранном продукте и отдельно от проектирования ключа.
Следующий шаг: проверить одну нагрузочную модель
Не начинайте с распределения всей базы. Возьмите один наиболее дорогой сценарий, его реальные ключи и профиль нагрузки. Сравните текущую схему с выбранным вариантом на тестовых данных, включая запросы, которые затрагивают несколько шардов. Измеряйте задержку, пропускную способность и перекос по узлам — без условий теста цифры нельзя переносить на вашу систему.
Для PostgreSQL 16 отдельно проверьте, решит ли задачу секционирование внутри кластера. Если оно не отвечает на проблему распределения между серверами, оцените стоимость маршрутизации в приложении и требования конкретной распределённой платформы. Решение о шардах оправдано не самим ростом таблицы, а доказанным ограничением и планом эксплуатации после перехода.
Источники: PostgreSQL 16: секционирование таблиц, Citus Data: документация
Частые вопросы
Как понять, что уже пора шардировать базу?
Секционирование PostgreSQL — это шардирование?
Какой ключ шарда выбрать для интернет-магазина?
Можно ли сначала попробовать шарды только для новых данных?
Что будет, если один шард станет недоступен?
Подход из статьи подойдёт для другой версии PostgreSQL?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.