На графиках одновременно растут CPU приложения и ожидание базы данных. Как установить, что является первичным узким местом?
Одновременный рост метрик не доказывает, что первичным узким местом является ресурс с большей утилизацией. Нужно проверить причинность: провести контролируемое изменение одного ресурса или типа нагрузки и посмотреть, изменятся ли вслед за ним задержка, очередь и пропускная способность.
Если уменьшение времени выполнения запросов к базе заметно снижает CPU приложения и сквозную задержку, вероятнее всего, первичной была база. Если же ограничение или оптимизация CPU приложения устраняет рост ожидания базы, первичным узким местом может быть приложение.
В анализе производительности давно используют не только графики утилизации, но и модели очередей и причинно-следственные эксперименты. Исходная проблема состоит в том, что зависимый компонент часто тоже выглядит перегруженным: медленная база удерживает потоки приложения, а неэффективное приложение может создавать лишнюю нагрузку на базу.
Поэтому диагностика постепенно сместилась от поиска ресурса с максимальным процентом загрузки к проверке того, какое изменение действительно улучшает поведение системы. Такой подход помогает не лечить симптом вместо причины.
Предположим, при росте нагрузки CPU приложения достигает 85%, а время ожидания ответа базы увеличивается в несколько раз. Простое решение — масштабировать приложение или увеличить CPU, но оно может не дать результата, если основная задержка возникает в базе.
Обратная ошибка также возможна: команда оптимизирует запросы, хотя приложение тратит CPU на сериализацию, шифрование или бесконечные повторы. В результате тест может показать кратковременное улучшение отдельной метрики, но целевой SLA и пропускная способность не изменятся.
Сначала нужно разложить сквозную задержку на составляющие: время в приложении, время ожидания пула соединений, время выполнения и ожидания базы, сетевые задержки, очереди и повторы. Для базы полезны показатели утилизации CPU и диска, длина очередей, длительность запросов, блокировки и насыщение пула соединений. Для приложения — CPU по процессам или потокам, сборка мусора при её наличии, размеры очередей, число активных запросов и время работы отдельных этапов.
Затем следует сопоставить события во времени и проверить направление зависимости. Рост ожидания базы, после которого растёт число занятых потоков приложения и его CPU, указывает на возможное распространение задержки вверх по цепочке. Но совпадение временных рядов само по себе недостаточно: общий всплеск нагрузки способен одновременно увеличить обе метрики.
Наиболее надёжный способ — контролируемая проверка с неизменным профилем запросов. Варианты проверки:
Первичным следует считать не ресурс с самой высокой утилизацией, а ограничение, устранение которого улучшает целевые показатели без переноса узкого места в другой компонент. Важно контролировать побочные эффекты: ускорение базы может только быстрее перегрузить приложение, а увеличение CPU приложения — увеличить поток запросов к базе.
В тесте оформления заказа CPU приложения достигал 82%, а ожидание базы занимало 40% времени запроса. Команда рассмотрела два варианта: добавить экземпляры приложения, что быстро увеличило бы вычислительный ресурс, но могло усилить нагрузку на базу, или оптимизировать медленный запрос, что требовало анализа плана выполнения и не гарантировало устранения CPU-затрат приложения.
Сначала повторили тест с тем же профилем нагрузки и заменили запрос на эквивалентный по результату, но выполняющийся в базе существенно быстрее. После этого снизились p95 задержки, CPU приложения и длина очереди запросов, а успешный RPS вырос. Это подтвердило, что ожидание базы было первичным ограничением, а высокий CPU приложения в исходном тесте был частично следствием удержания большого числа активных операций и сопутствующей обработки.
Нет. Процент утилизации показывает занятость ресурса, но не его причинную роль. Ресурс может быть загружен из-за работы, вызванной другим узким местом, а низкая утилизация иногда сопровождает насыщение очереди, блокировку или ограничение пропускной способности на другом уровне.
Нужно связывать утилизацию с задержкой, очередями и изменением пропускной способности при росте нагрузки. Особенно полезно проверить, улучшились ли целевые показатели после контролируемого изменения конкретного ресурса.
Нужно разделить время получения соединения из пула и время выполнения запроса после получения соединения. Рост очереди на получение соединения при нормальной загрузке базы указывает на слишком маленький пул, зависшие операции или избыточную длительность обработки в приложении, а не обязательно на дефицит ресурсов базы.
Если же соединения доступны, но сами запросы долго выполняются, следует анализировать базу: планы запросов, блокировки, дисковые и вычислительные очереди. Без такого разделения увеличение размера пула может только усилить нагрузку на базу и ухудшить ситуацию.
Это нормальный результат устранения ограничения в многоступенчатой системе. После каждого изменения нужно повторно измерять сквозную задержку, успешный RPS, ошибки, очереди и утилизацию всех существенных компонентов, а не объявлять успехом улучшение одной метрики.
Например, ускорение базы может увеличить поток ответов и перегрузить CPU приложения или сетевой канал. Корректная цель — найти конфигурацию, при которой система выдерживает требуемый профиль нагрузки и SLA; единственного постоянного узкого места у системы может не быть.