Прямой ответ
NewSQL — класс систем, которые сочетают SQL и транзакционные гарантии реляционных СУБД с горизонтальным масштабированием, характерным для NoSQL. Представители: CockroachDB, TiDB, YugabyteDB, а также Spanner как родоначальник направления.
Общая архитектура:
- Данные разбиваются на диапазоны (range в CockroachDB, region в TiDB) по первичному ключу.
- Каждый диапазон реплицируется на несколько узлов; согласованность реплик обеспечивает консенсус-протокол, обычно Raft — см. алгоритм Raft.
- SQL-слой разбирает запрос, строит план и координирует выполнение на нескольких узлах.
- Транзакции выполняются распределённо с использованием меток времени и многоверсионности.
Что это даёт на практике:
- Масштабирование добавлением узлов вместо вертикального роста одной машины.
- Отсутствие единой точки отказа: отказ узла не останавливает работу, диапазоны переходят к другим репликам.
- Сохранение SQL: существующие запросы и ORM работают с минимальными изменениями.
- Автоматическое шардирование: разработчику не нужно выбирать ключ шардирования — о сложностях ручного выбора в статье про шардирование.
Цена такого устройства:
| Аспект | Влияние |
|---|---|
| Задержка записи | Выше из-за консенсуса между репликами |
| Распределённая транзакция | Дороже локальной: несколько раундов обмена |
| Соединения между диапазонами | Требуют координации между узлами |
| Последовательности и автоинкремент | Могут выдавать значения с пропусками |
| Географическое распределение | Задержка определяется расстоянием между центрами |
Принципиальное ограничение описывается CAP-теоремой: при разделении сети система выбирает между доступностью и согласованностью. NewSQL-системы обычно выбирают согласованность, поэтому при изоляции части узлов запись в них прекращается — см. CAP-теорему.
-- CockroachDB: привычный SQL, данные распределены автоматически
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
customer_id UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
total DECIMAL(12,2) NOT NULL
);
-- локальность реплик можно задать явно
ALTER TABLE orders CONFIGURE ZONE USING num_replicas = 3;
Практика: когда переход оправдан
Признаки, что вертикальное масштабирование исчерпано:
- Объём данных или нагрузка записи превышают возможности одной машины, и рост продолжается.
- Ручное шардирование уже реализовано и стало основным источником сложности и ошибок.
- Требуется доступность при отказе целой зоны или региона.
Признаки, что переход преждевременен:
- Данные помещаются на одной машине с запасом на годы вперёд.
- Основные запросы — аналитические агрегации; для них подходит колоночное хранилище.
- Команда не готова эксплуатировать кластер: мониторинг, обновления, восстановление.
Рекомендации:
- Проектируйте первичный ключ под распределение. Монотонно растущий ключ создаёт горячий диапазон на одном узле. Практика — UUID или составной ключ с хорошим распределением.
- Держите связанные данные вместе. Запросы, постоянно соединяющие две таблицы, выигрывают от одинакового ключа локальности; иначе каждый запрос становится распределённым.
- Измеряйте задержку до перехода. Консенсус добавляет миллисекунды к каждой записи. Для сценариев с тысячами записей в секунду на одну сущность это может быть критично.
- Проверяйте совместимость SQL. Совместимость с PostgreSQL или MySQL высока, но не полна: отдельные конструкции, расширения и типы могут отсутствовать.
- Планируйте восстановление. Распределённая система не отменяет ошибок приложения: логическое повреждение данных replicated на все реплики. Резервные копии остаются обязательными.
Практический сценарий: оценка перехода с шардированного PostgreSQL
Контекст: сервис работал на PostgreSQL с ручным шардированием по 16 базам. Добавление шарда требовало недели работы и остановки части операций.
- Анализ запросов. 78 % запросов обращались к данным одного клиента, 14 % требовали соединения данных двух таблиц по ключу клиента, 8 % — аналитические агрегации по всему набору.
- Прототип. Развернули CockroachDB, перенесли схему и прогнали типовые запросы на копии данных объёмом 2 ТБ.
- Результаты измерения. Запросы по ключу клиента: p95 вырос с 4 до 9 мс. Записи: p95 вырос с 5 до 18 мс из-за консенсуса. Аналитические агрегации: медленнее в 3–6 раз, их решили оставить в хранилище.
- Решение. Переход признан оправданным: рост нагрузки требовал добавления шардов каждые четыре месяца, а задержка в пределах 20 мс для сценариев сервиса допустима. Аналитику вывели в отдельный контур.
- Что учли дополнительно. Перевели первичный ключ на UUID, чтобы избежать горячего диапазона; настроили локальность реплик по регионам; оставили резервное копирование, потому что консенсус не защищает от логических ошибок.
Вывод: NewSQL решает конкретную проблему — масштабирование транзакционной нагрузки без ручного шардирования. Если этой проблемы нет, дополнительные задержки и сложность эксплуатации не окупаются.
FAQ
Чем NewSQL отличается от шардированной реляционной базы? Шардирование выполняется системой автоматически, а транзакции и соединения работают поверх распределённого хранилища. При ручном шардировании эти задачи решает приложение, и распределённая транзакция обычно не поддерживается.
Заменяет ли NewSQL аналитическое хранилище? Нет. Массовые агрегации по всему набору данных эффективнее выполняются колоночными системами. NewSQL ориентирован на транзакционные нагрузки с точечными запросами.
Что происходит при сетевом разделении? Большинство таких систем выбирает согласованность: диапазоны, оказавшиеся в меньшинстве, перестают принимать запись до восстановления соединения. Чтение в некоторых конфигурациях может продолжаться с устаревших реплик.
Можно ли начать с одной ноды и расти позже? Да, это обычный путь: кластер из одного узла ведёт себя как обычная СУБД, а масштабирование выполняется добавлением узлов без изменения схемы. Такой старт снижает риск, но не отменяет необходимости сразу учитывать распределённость в проектировании ключей.
Источники: CockroachDB docs, TiDB docs, Raft (описание алгоритма) — ссылки в шапке.