Azure Cosmos DB: где настройка по умолчанию не держит нагрузку
Azure Cosmos DB прощает многое на стенде с одним разработчиком и почти сразу начинает мешать в проде. Настройка по умолчанию предполагает, что ключ раздела вы выберете осознанно, а ёмкость выделите под реальный профиль запросов — если этого не сделать, первым делом появляется горячий раздел: одна логическая группа принимает непропорционально много операций, и запросы к ней начинают отдавать отказы по нехватке пропускной способности, хотя общий запас вроде бы есть.
Чаще всего ошибка ключа раздела родом из модели данных, а не из конфигурации. Если ключом выбрано поле с малой кардинальностью или поле, по которому идёт фильтрация в отчётах, запрос становится кросс-партиционным: он опрашивает все разделы, съедает единицы запросов пачками и растёт по времени вместе с объёмом коллекции. Симптомы узнаваемы — нестабильная задержка запросов на пиках, заметный разброс между быстрыми и медленными вызовами, «пила» по потреблению ёмкости, из-за которой приходится держать запас выше расчётного.
Отдельная история — ручные правки в консоли: индексы, уровни согласованности, политики времени жизни и профили масштабирования, выставленные «по-быстрому» во время инцидента. Работает, но среда перестаёт воспроизводиться: тест и прод расходятся, развёртывание новой копии не даёт ожидаемого поведения, а следующая правка снова делается руками.
Лимиты ёмкости при этом не лечатся поднятием потолка: без нормализации ключа раздела и индексов растёт не пропускная способность, а счёт за каждую операцию.
Дальше разбираем, как это закрывается — от выбора ключа и режима ёмкости до описания конфигурации кодом, чтобы окружения собирались одинаково.
Что даёт выверенная конфигурация хранилища
Выверенная конфигурация Azure Cosmos DB — это не разовый запуск, а набор параметров, каждый из которых виден в метриках: ключ раздела, политика индексирования, уровень согласованности, запас пропускной способности. Их сочетание определяет, сколько операций проходит без повторных попыток и как быстро возвращается ответ.
Снижение доли отказов при пиковых всплесках
Пиковый всплеск ломает не хранилище, а распределение нагрузки: один горячий ключ раздела собирает основную часть записи и начинает отдавать отказ по превышению пропускной способности. Мы выравниваем ключ по реальным шаблонам доступа, добавляем запас и автомасштабирование под суточный профиль — доля отказов на пиках уходит к десятым долям процента, а лавина повторных попыток не запускается.
Предсказуемый отклик на чтение и запись
Задержку чтения создаёт не сеть, а сканирование: запрос без ключа раздела перебирает лишние документы, и время ответа растёт вместе с объёмом данных. Точечное чтение по ключу и покрывающие индексы под конкретные фильтры делают отклик ровным. Индексация и расход ёмкости связаны напрямую: политика по нужным путям вместо «индексировать всё» снижает стоимость записи, и освободившийся ресурс уходит на полезную нагрузку.
Что фиксируем в отчёте по итогам:
- доля отказов на пиках и в часы спада;
- время отклика чтения и записи по ключевым шаблонам запросов;
- доля операций, прошедших без повторных попыток;
- разброс отклика между рабочими часами и пиком.
Режимы согласованности и модели ёмкости
Режим согласованности и модель ёмкости в Azure Cosmos DB выбирают вместе с ключом раздела: от ключа зависит шардирование, а от него — как поведёт себя автоматическое масштабирование на пиках. Сменить эти решения после запуска затратнее по времени, чем обсудить на старте.
Согласованность: что теряем и что получаем
Чем строже режим согласованности, тем выше задержка чтения и нагрузка на репликацию, зато приложение не видит устаревших данных. Уровень подбирают под операцию: расчётам нужно строгое чтение, а ленты и счётчики живут на сеансовой или итоговой согласованности.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Строгая | Расчёты, где расхождение недопустимо | Наибольшая задержка чтения |
| Ограниченное устаревание | Отставание чтения в заданном окне допустимо | Окно контролирует приложение |
| Сеансовая | Чтение своих же записей | Порядок между сессиями не гарантирован |
| Выделенная ёмкость | Ровный предсказуемый поток | Резерв не освобождается сам, масштаб вручную |
| Эластичная ёмкость | Пульсирующая нагрузка и пики | Масштабирование реагирует с задержкой |
Выделенная ёмкость против эластичной
Выделенная ёмкость держит постоянный резерв и подходит сервисам с ровным трафиком; эластичная подстраивается сама, но реакция на пик идёт с задержкой. Мы считаем профиль нагрузки по реальным запросам и выбираем ключ раздела так, чтобы шардирование распределяло данные равномерно и не появлялось горячих разделов.
Как мы ведём работы в Azure: от аудита до передачи
На входе снимаем список контейнеров, текущие ключи разделов и профиль нагрузок: как растут данные, где запросы читают несколько разделов, какие пики потребления приходятся на часы отчётности. Параллельно фиксируем требования — допустимое окно недоступности, глубину восстановления и то, кто владеет инфраструктурой после передачи.
Что уточняем на входе
Нужны те же вводные, что и вашей команде: карта запросов и их частоты, объём и прирост данных, ограничения по согласованности, привычный способ развёртывания и регламент доступа к секретам. Без этого схема разделов проектируется наугад.
- Аудит схемы разделов. Разбираем ключи разделов, индексы и профиль запросов: где чтение идёт по всем разделам, какие из них упираются в потолок на пике. На выходе — карта узких мест и вердикт по раскладке.
- Проект разделения и режима согласованности. Подбираем ключ под реальные запросы, проверяем рост разделов и выбираем уровень согласованности — он влияет на задержку и на допустимые расхождения между репликами.
- Инфраструктура как код. Контейнеры, пропускную способность, индексы и роли доступа описываем декларативно: конфигурация живёт в репозитории, проходит проверку и разворачивается в нескольких средах одинаково.
- Настройка Cosmos DB через Terraform и миграция без простоя. Поднимаем новую раскладку рядом с рабочей, переключаем трафик поэтапно и переносим данные под контролем отставания. Окно недоступности — ноль, откат на прежнюю схему остаётся наготове.
- Проверка на нагрузочном профиле. Прогоняем пиковый и затяжной сценарии, смотрим поведение при росте разделов, настраиваем оповещения и правила масштабирования. Регламент резервного копирования фиксируем письменно и проверяем восстановление.
- Передача и обучение команды. Отдаём репозиторий, схему сред, политики доступа и порядок изменений, проводим разбор с инженерами — сопровождение идёт без нас.
Что остаётся у вас после внедрения: конфигурации и регламенты
Инфраструктуру мы не оставляем «чёрным ящиком»: вместе с работающим кластером вы получаете артефакты, по которым её можно развивать и эксплуатировать своими силами. Описание хранится в вашем репозитории под контролем версий — изменения проходят ревью, а не правки вручную в консоли.
Состав передаваемой документации
- Конфигурация как код. Модули описания баз Cosmos DB, учётных записей, уровня согласованности и политик резервирования, с отдельным набором переменных под тестовый и промышленный контуры.
- Схемы разделения и индексов. Карта ключей секционирования с обоснованием выбора, политики индексирования по контейнерам и расчёт пропускной способности под профиль нагрузки.
- Политики доступа и роли. Матрица «кто и что может», привязка прав к сервисным учётным записям и управляемым удостоверениям, принцип минимально необходимых привилегий.
- Схемы и диаграммы. Топология размещения, репликация между регионами, перечень точек отказа и порядок переключения трафика.
- Регламент резервного копирования. Периодичность снимков, сроки хранения и пошаговый сценарий восстановления с проверкой целостности данных.
- Инструкция по инцидентам. Типовые отказы — исчерпание пропускной способности, отказ части запросов, рост задержек: что смотреть и какой параметр менять.
- Регламенты эксплуатации. Порядок выпуска изменений, окна обслуживания, контроль стоимости запросов и правила вывода новых контейнеров.
Каждый документ привязан к фактическому состоянию среды и обновляется вместе с ней: регламент, оторванный от кода, быстро расходится с реальностью.
Кейс: пересборка схемы разделов под пиковую нагрузку
Арендаторный сервис: заказы, склад, отчёты. Контейнеры в Azure Cosmos DB росли вместе с числом клиентов, и на сезонных пиках запросы начинали отваливаться. Разбирали не нагрузку, а схему разделов: её когда-то спроектировали под ровный поток, а не под пик.
Что было до
Ключом раздела служил идентификатор клиента. У крупных арендаторов в разделе собирались десятки миллионов документов, у остальных разделы простаивали — часть физических разделов работала на пределе. Массовая выгрузка по крупному клиенту поднимала потребление до потолка, и база отвечала отказами по превышению лимита: на пике доля неуспешных запросов доходила до нескольких процентов. Отдельная проблема — индексировались все поля подряд, и каждая запись тянула перестроение индекса.
Что стало после
Перешли на составной ключ: арендатор плюс временное окно — месяц для операционных документов, год для архива. Клиентов, у которых окно оставалось горячим, развели синтетическим суффиксом из восьми сегментов от хеша идентификатора. Отчёты вынесли в отдельный контейнер со своим ключом, индексацию сузили до полей реальных фильтров, у архивной истории включили срок жизни документа.
Доля отказов по лимитам на пике упала с нескольких процентов до десятых долей, время ответа на тяжёлых запросах сократилось в разы, разброс нагрузки между горячими и холодными разделами — в пределах одного порядка вместо двух. Данных стало втрое больше при прежней пропускной способности.
Ушёл класс отказов, при котором один арендатор выедал раздел и ронял отклик для всех. Схема переносится на любую арендаторную модель: ключ раздела выбирается по картине доступа, а не по структуре сущностей.
Что делать, если база уже развёрнута и растёт нагрузка?
Перестроить схему разделов на живых данных можно — но не «на месте». Ключ раздела определяет физическое размещение документов, поэтому в существующем контейнере он не меняется: поднимается новый контейнер и данные переносятся в него, пока уже развёрнутая база Cosmos DB продолжает обслуживать трафик. Это проходит без остановки сервиса, если приложение умеет работать с двумя ключами одновременно.
Порядок такой: снимаем профиль нагрузки и распределение данных по текущему ключу, выбираем новый по кардинальности и равномерности, включаем двойную запись в целевой контейнер. Дальше фоновый перенос с проверкой контрольных сумм по логическим разделам, постепенное переключение читателей, и только после сверки — отключение старого контура.
Обратная совместимость приложения закладывается заранее: слой доступа читает по обоим ключам, а пишет в новый, поэтому откат занимает минуты, а не часы. Переход между моделями ёмкости так плавно не проходит — смена режима затрагивает уровень аккаунта, поэтому планируется короткое окно сопровождения с прогревом и проверкой ключевых сценариев сразу после.
Что даёт пересборка схемы разделов: кросс-раздельные запросы перестают съедать общую пропускную способность, самые нагруженные логические разделы больше не упираются в потолок, а рост данных снова ложится равномерно. Начинаем с замеров, а не с переключения — тогда решение опирается на профиль нагрузки, а не на догадки.
Спорные места: согласованность, индексы, доступ
Почти каждое решение по Cosmos DB — компромисс между задержкой, доступностью и расходом единиц запроса. На ревью перед запуском всплывают одни и те же сомнения — ниже короткие ответы на те, что чаще всего тормозят согласование.
Насколько строгую согласованность брать?
Строгая даёт линейные операции, но привязывает чтение к области записи: растёт задержка и падает доступность при потере региона. Уровень session закрывает большинство сценариев — клиент читает собственные записи. Держим его по умолчанию, строгий включаем точечно.
Индексировать все поля — это нормально?
Нет: каждый лишний путь добавляет расход единиц запроса на запись и раздувает хранилище. Исключаем поля без фильтров и сортировок, под конкретные шаблоны запросов оставляем составные индексы и сверяем политику с журналом запросов до вывода в бой.
Можно ли обойтись без мастер-ключа в приложении?
Да, через управляемые удостоверения и роли — встроенные или кастомные, с областью на аккаунт, базу или коллекцию. Ключ остаётся в секрет-хранилище только для миграций и ротируется по расписанию.
Что даёт резервное копирование и как восстанавливаться?
Периодические копии с окном хранения или непрерывный режим. Восстановление идёт не поверх, а в новый аккаунт: строку подключения и доступы настраиваем заново, поэтому переключение отрабатываем заранее.
Кто съедает бюджет обработки запросов?
Чаще всего не источник, а «горячие» секции разделов: при перекосе ключа разделения почти весь поток идёт в одну часть. Смотрим метрики по секциям, профилируем тяжёлые запросы и перераспределяем ключ либо выносим чтение в отдельную модель.
Обсудим задачу и вернёмся с планом работ
Чтобы оценка работ опиралась на факты, а не на предположения, соберём входной набор данных. Ниже — что прислать до созвона; при ограниченном доступе к продакшену часть пунктов заменяется обезличенными выгрузками.
- Схему данных: контейнеры, ключи партиционирования, текущие индексы и TTL, модель согласованности, объёмы и скорость роста коллекций.
- Профиль нагрузки: запросы в секунду и соотношение чтения и записи, размер документа, пиковые окна, географию клиентов и распределение по регионам.
- Текущие конфигурации: режим пропускной способности, уровни согласованности, политики индексирования, настройки резервного копирования, описания инфраструктуры и состояние, если ресурсы уже под управлением Terraform.
- Доступы для аудита: чтение в подписку, метрики, журналы диагностики и логи медленных запросов; достаточно обезличенных выгрузок.
- Требования и ограничения: целевое время восстановления и допустимая точка потери данных, регуляторные нормы, окна обслуживания, порядок согласования изменений.
- Критерии готовности: задержка на 95-м процентиле, доля запросов без ограничения пропускной способности, предсказуемость роста хранилища.
На созвоне разберём эти данные и вернёмся с оценкой работ, планом внедрения по этапам с точками отката, порядком передачи документации и вариантами поддержки после запуска.







