Короткий ответ
Основные пути — шардирование данных между несколькими независимыми инстансами по ключу, разделение нагрузки по функциональному домену (database per service) или миграция части данных на распределённую СУБД с горизонтально масштабируемой записью; каждый вариант меняет модель согласованности и требует существенной переработки приложения, поэтому выбор зависит от того, какие гарантии консистентности действительно нужны бизнесу.
Как это работает подробнее
шардирование распределяет строки между несколькими независимыми базами по выбранному ключу, что масштабирует запись линейно, но делает кросс-шардовые запросы и транзакции существенно сложнее; разделение по домену снижает нагрузку на любую одну базу, но требует отказа от кросс-доменных транзакций в пользу эвентуальной консистентности; распределённые СУБД решают проблему на уровне движка ценой части гарантий или гибкости запросов.
Пример кода
Вариант А (шардирование по customer_id):
shard-1 (customers 0-999999), shard-2 (customers 1000000-1999999), ...
Кросс-шардовые отчёты требуют агрегации на уровне приложения/отдельного аналитического хранилища
Вариант Б (database per service):
orders-db, inventory-db, billing-db — независимые базы,
согласованность между ними — через события/эвентуальную консистентность
Вариант В (распределённая СУБД):
миграция горячих таблиц на СУБД с нативным горизонтальным масштабированием записи,
с пересмотром части запросов под её ограниченияЧто использовать на практике
- Рекомендация. перед выбором пути подробно анализируют реальный паттерн нагрузки — какая доля запросов кросс-шардовая, насколько критична строгая консистентность для конкретных операций, и насколько велика будет стоимость переписывания приложения; часто временным шагом служит дальнейшая оптимизация (индексы, кэширование чтения) прежде чем идти на архитектурно необратимое решение.
- Проверка. после внедрения выбранного варианта нагрузочный тест должен показать линейный (или близкий к линейному) рост пропускной способности записи при добавлении шардов/узлов, в отличие от прежнего плато на одном инстансе.
- Компромисс. шардирование и разделение по домену сохраняют знакомую реляционную модель, но перекладывают сложность на уровень приложения и операционных процессов; распределённая СУБД снимает часть этой сложности с приложения, но требует смены технологии, переобучения команды и может ограничить доступные гарантии консистентности — выбор должен основываться на том, какие операции бизнес-критичны и какую сложность команда готова поддерживать, а не на предположении, что одно решение универсально лучше.
Подводные камни
- Риск. начинать с самого радикального решения без предварительной попытки оптимизации схемы и индексов
- Риск. выбирать ключ шардирования без анализа реального распределения нагрузки, получая «горячий» шард
- Риск. недооценивать объём изменений в приложении (роутинг запросов, обработка кросс-шардовых операций, миграция данных без простоя).