Базы данных возможной: критерии выбора СУБД под высокие нагрузки
СУБД под высокой нагрузкой выбирают не по числу запросов в рекламном бенчмарке. Выбор определяет профиль операций: сколько система читает и записывает, какие задержки допустимы, нужна ли строгая…

СУБД под высокой нагрузкой выбирают не по числу запросов в рекламном бенчмарке. Выбор определяет профиль операций: сколько система читает и записывает, какие задержки допустимы, нужна ли строгая согласованность между узлами и что должно происходить при отказе сервера. Ошибка на этом уровне обычно проявляется позже: растут задержки, реплики отстают, а масштабирование превращается в миграцию с остановкой сервиса.
Запрос «базы данных возможной» выглядит как незавершенная формулировка. Для инженерного решения важнее уточнить, какую архитектуру система должна поддерживать и при каких ограничениях. Ниже — последовательность оценки: сначала нагрузка и запросы, затем консистентность, масштабирование и отказоустойчивость. Такой порядок помогает не вводить распределенную архитектуру раньше, чем исчерпаны настройки отдельного узла.
Профиль операций задает требования к СУБД
Первый шаг — описать нагрузку в терминах приложения. Среднее число запросов мало что говорит без разбивки по типам. Система с большим количеством чтений и редкими изменениями данных предъявляет иные требования, чем сервис, который постоянно записывает события или обновляет состояние заказов.
Для начала фиксируют:
- долю операций чтения и записи, включая обновления и удаления;
- типичные и наиболее дорогие запросы;
- размеры записываемых данных и частоту пакетных операций;
- требования к задержке для пользовательских и фоновых запросов;
- характер всплесков: постоянная нагрузка или краткие пики;
- допустимое время отставания реплик и потери доступности при отказе.
Разделяйте профиль приложения и профиль базы. Например, операция, которую бизнес называет чтением, может включать несколько запросов, агрегацию и проверку прав. Запись может запускать каскадные обновления, индексирование и публикацию события. Нагрузку следует оценивать по фактическому плану выполнения запросов, а не по названию эндпоинта.
Бенчмарк имеет смысл только при совпадении условий. Сравнивать СУБД можно на одной схеме, с теми же индексами, данными, запросами, настройками долговечности и аппаратной конфигурацией. Показатель TPS без этих параметров не переносится на продакшен. Он описывает конкретный тест, а не универсальную производительность продукта.
Перед сменой класса СУБД проверьте узкие места текущей системы. Медленные запросы, неудачные планы выполнения, лишние индексы и недостаток памяти могут ограничивать один узел сильнее, чем выбранная модель хранения. Индекс ускоряет поиск по нужному условию, но увеличивает стоимость записи и занимает место. Индексировать каждое поле «на всякий случай» — способ ухудшить нагрузку на запись, не гарантируя ускорения чтения.
Практический порядок диагностики выглядит так:
1. Снимите профиль нагрузки на уровне запросов: частота, задержка, объем чтения и записи.
2. Найдите запросы с наибольшим суммарным влиянием на время ответа, а не только самые медленные единичные вызовы.
3. Проверьте план выполнения и соответствие индексов фильтрам, сортировкам и соединениям.
4. Повторите тест на репрезентативном объеме данных и в условиях, близких к боевым.
5. Только после этого оценивайте необходимость репликации, шардирования или перехода на распределенную СУБД.
Масштабирование не исправляет неэффективный запрос. Оно распределяет его стоимость по большему числу узлов.
При выборе базы данных под нагрузку учитывайте также форму данных и связи между ними. Реляционная модель подходит, когда важны ограничения целостности, транзакции и запросы с соединениями. Документная или ключ-значение модель может оказаться удобнее при заранее известном способе доступа и структуре данных, но сама по себе не дает гарантии высокой скорости. Производительность зависит от модели, схемы, индексов и поведения конкретных запросов.
Консистентность: требования приложения важнее ярлыка
ACID описывает свойства транзакций: атомарность, согласованность, изоляцию и долговечность. Для приложений, где несколько изменений должны фиксироваться как единое целое, эти гарантии имеют прямое значение. Например, операция может одновременно менять состояние записи и связанные данные. Если система допускает частичное применение такой операции, приложение должно самостоятельно обрабатывать последствия.
В распределенной среде к требованиям добавляется поведение при проблемах сети. CAP-теорема описывает компромисс между согласованностью и доступностью во время сетевого разделения. Она не служит простым рейтингом СУБД и не означает, что для каждой системы достаточно выбрать одну букву. В нормальном режиме система может предоставлять согласованное чтение; при потере связи между частями кластера поведение зависит от архитектуры и настроек.
BASE обычно используют как обозначение подхода, допускающего ограниченную временную несогласованность ради доступности и масштабирования. Это не точная противоположность ACID и не характеристика, которая автоматически делает систему подходящей для Highload. Нужно определить, какие расхождения допустимы, как долго они могут сохраняться и как приложение обнаруживает или исправляет конфликт.
Сформулируйте требования на уровне конкретных операций:
- Должна ли запись быть видна следующему чтению сразу после подтверждения?
- Может ли пользователь временно увидеть устаревшее состояние?
- Допустимо ли повторное выполнение операции после тайм-аута?
- Как разрешаются параллельные изменения одной сущности?
- Какие данные нельзя терять после подтверждения записи?
Ответы могут различаться даже внутри одного продукта. Например, финансовое состояние и вторичная аналитическая витрина могут иметь разные требования к согласованности и задержке обновления. Сводить их к одному универсальному режиму часто невыгодно: либо система получает избыточные гарантии там, где они не нужны, либо критическая операция оказывается слабее требуемого уровня.
Для межрегионального обмена важна физическая задержка сети. RTT между Европой и США составляет примерно 100 мс. Синхронное подтверждение записи между такими регионами добавляет сетевой обмен в путь операции. Поэтому обычно синхронную репликацию используют внутри площадки или близкого сегмента инфраструктуры, а между регионами строят асинхронную передачу. Это влияет на допустимое отставание и на сценарий восстановления после аварии.
В спецификации следует описывать не абстрактную «сильную консистентность», а ожидаемое поведение приложения: что подтверждается пользователю, когда данные становятся доступны на репликах и что происходит при потере связи. Это позволяет сравнивать системы по реальным гарантиям, а не по маркетинговым терминам.
Чтение и запись масштабируются разными способами
Репликация Primary-Replica распределяет чтение между копиями данных. Записи направляются на основной узел, а изменения передаются репликам. Это снижает нагрузку на primary от запросов SELECT, но не превращает систему в кластер с линейно масштабируемой записью. Более того, чтение с реплики может вернуть устаревшие данные, если реплика отстает.
Для каждого типа чтения нужно решить, допустима ли eventual consistency. Запрос состояния сразу после изменения обычно направляют на primary или выполняют с гарантией чтения собственных записей. Для менее чувствительных операций, например части отчетов, чтение с реплики может быть приемлемым. Универсальная маршрутизация всех SELECT на реплики создаёт трудноуловимые ошибки: пользователь записал изменение и тут же получил прежнее значение.
Шардирование распределяет данные по нескольким узлам и применяется для масштабирования записи и объема хранения. Это отдельная архитектурная сложность. Запросы между шардами, глобальные ограничения, транзакции и изменение ключа распределения требуют дополнительных механизмов. Поэтому сначала исчерпывают оптимизацию запросов, индексов и конфигурации отдельного узла. Шардирование вводят, когда измерения подтверждают, что предел одного узла стал реальным ограничением.
| Подход | Что распределяет | Основной эффект | Цена и риск |
|---|---|---|---|
| Репликация Primary-Replica | Запросы чтения | Снижает нагрузку SELECT на primary | Отставание реплик, чтение устаревших данных |
| Range-шардирование | Данные по диапазонам ключа | Удобно для запросов по диапазону и временным сегментам | Неравномерное распределение при горячих диапазонах |
| Hash-шардирование | Данные по хешу ключа | Обычно распределяет записи равномернее | Запросы по диапазонам сложнее маршрутизировать |
| Geo-partitioning | Данные по географии | Поддерживает локальность и региональные требования | Перемещение данных и межрегиональные запросы сложнее |
| Directory-based | Маршрутизацию через каталог соответствий | Даёт гибкость в размещении отдельных ключей | Каталог становится компонентом, который нужно масштабировать и защищать |
Ключ шарда определяет поведение системы сильнее, чем название алгоритма. Если большая часть запросов обращается к одному ключу, возникает горячий шард. Если ключ распределяет записи равномерно, но запросы часто выбирают диапазон значений, часть операций может затрагивать несколько узлов. Критерии выбора СУБД поэтому включают не только поддержку шардирования, но и возможность эффективно маршрутизировать реальные запросы.
При проектировании шард-ключа проверьте три вещи. Во-первых, насколько равномерно по нему распределяются данные и записи. Во-вторых, совпадает ли он с фильтрами основных запросов. В-третьих, что произойдет при росте объема: потребуется ли перераспределять данные и как приложение переживет этот процесс. Выбор ключа, который удобен сегодня, но создаёт крупные межшардовые операции завтра, переносит проблему, а не решает её.
Отказоустойчивость и кворум
Репликация нужна не только для производительности. Она повышает устойчивость к отказу узла, но наличие копий ещё не определяет, сможет ли кластер безопасно продолжить работу. Для согласованного принятия решений распределённым системам требуется кворум. Базовая архитектура для отказоустойчивого кластера предполагает хранение данных как минимум на трёх независимых серверах. Это позволяет пережить вывод одного узла на обслуживание без потери большинства голосов.
Слово «независимых» здесь принципиально. Три виртуальные машины на одном физическом сервере не защищают от отказа этого сервера. Узлы следует распределять с учётом доменов отказа: оборудования, стоек, зон доступности или площадок. Конкретная схема зависит от инфраструктуры и требований по времени восстановления.
Отдельно задайте параметры восстановления:
- RPO — сколько подтверждённых данных допустимо потерять при аварии.
- RTO — сколько времени сервис может оставаться недоступным до восстановления.
- Порядок выборов нового primary и поведение клиентов при переключении.
- Условия возврата отставшего узла в кластер и синхронизации данных.
- Реакцию на сетевое разделение, когда узлы доступны, но не могут связаться между собой.
Проверка отказоустойчивости должна включать не только выключение одного сервера. Проверьте потерю связи, недоступность зоны, заполнение диска и возврат узла после длительного простоя. Также проверьте, что происходит с соединениями приложения при переключении: часть ошибок может быть связана не с базой, а с пулом подключений, тайм-аутами и повторными запросами.
Повтор запроса после тайм-аута требует отдельной осторожности. Клиент мог не получить подтверждение, хотя запись уже прошла. Если операция не идемпотентна, повтор способен создать дубликат или применить изменение дважды. Решение обычно находится на уровне протокола приложения: ключ идемпотентности, уникальное ограничение или проверка состояния операции. Одной настройки кластера для этого недостаточно.
Кворум и резервная копия решают разные задачи. Кворум поддерживает работу кластера при отказе узла. Резервная копия позволяет восстановить данные после логической ошибки, повреждения или нежелательного изменения, которое уже распространилось по репликам. В архитектуре нужны оба механизма, а восстановление из копии следует проверять на практике.
Distributed SQL и NewSQL: реляционная модель на нескольких узлах
Распределенные SQL-системы, часто относимые к классу NewSQL, совмещают реляционную модель и транзакционные гарантии с горизонтальным распределением данных. Пример такого подхода — Google Spanner. В подобных системах шардирование сочетается с распределенным консенсусом, например на основе Paxos или Raft, для управления состоянием групп узлов.
Это позволяет строить реляционные кластеры с ACID-гарантиями поверх нескольких серверов. При этом распределение не исчезает из приложения как инженерная проблема. Сетевые задержки влияют на транзакции, межшардовые операции требуют координации, а доступность зависит от кворума и топологии. Транзакция, затрагивающая несколько шардов, обычно сложнее локальной операции и может иметь более высокую задержку.
Распределенная SQL-СУБД имеет смысл оценивать, когда одновременно нужны реляционная модель, горизонтальное масштабирование и транзакционные гарантии между узлами. Если нагрузка помещается на одном узле после настройки запросов и индексов, переход добавит компоненты и режимы отказа без гарантированной выгоды. Если система упирается в запись, а запросы требуют согласованных изменений между сущностями, распределенный SQL может сократить количество самописной координации, но стоимость этой архитектуры нужно измерить на рабочих сценариях.
Сравнение следует строить на сценариях приложения. Подготовьте набор критичных транзакций, запросов чтения, отказных ситуаций и операций восстановления. Измеряйте задержку, пропускную способность, поведение при отказе узла, время возврата реплики и сложность изменения схемы. Не переносите результат теста на другой профиль нагрузки: абсолютные RPS и TPS без конфигурации, схемы и топологии не являются критерием выбора.
Рынок СУБД и инструментов обработки данных в России в 2025 году оценивался в 101,9 млрд рублей; на программные лицензии приходилось 80%, на внедрение и поддержку — 20%. Для архитектурного решения эти доли не определяют технический выбор, но напоминают о расходах за пределами лицензии. Миграция, эксплуатация кластера, мониторинг, резервное копирование и компетенции команды входят в стоимость системы наравне с программным продуктом.
Порядок выбора
Зафиксируйте требования до сравнения конкретных СУБД. Иначе тест будет отвечать на вопрос, какая система быстрее в произвольной конфигурации, а не какая выдержит профиль приложения.
1. Опишите операции и нагрузку: чтения, записи, пики, размеры данных и критичные запросы.
2. Установите требования к транзакциям и видимости изменений, включая допустимое отставание реплик.
3. Оптимизируйте текущий узел: планы запросов, индексы, память, дисковую подсистему и настройки соединений.
4. Определите, что именно ограничивает систему. Для чтения рассмотрите репликацию; для записи и объема — шардирование или распределенную СУБД.
5. Спроектируйте ключ распределения на основе запросов и равномерности данных. Проверьте риск горячих шардов и межшардовых операций.
6. Опишите отказные сценарии через RPO, RTO, кворум, резервные копии и порядок восстановления.
7. Проведите бенчмарк на одной схеме и сопоставимых условиях, затем проверьте деградацию при отказах и росте данных.
Архитектуру следует считать неподходящей, если она требует от приложения гарантий, которых СУБД не предоставляет, если ключ распределения концентрирует нагрузку на одном шарде или если восстановление кластера не укладывается в требования сервиса. Такие ограничения нужно выявлять до деплоя, а не после первого инцидента.
Выбор СУБД под Highload начинается с измерений и контракта данных. Репликация решает задачу чтения, шардирование распределяет данные и интенсивную запись, а распределенный SQL добавляет координацию и транзакционные гарантии ценой сетевых обменов. Универсальной базы данных для любой возможной архитектуры нет. Есть система, чьи свойства совпадают с нагрузкой, требованиями консистентности и допустимыми режимами отказа.