Ресурсопотребление и метрики
Ресурсопотребление и метрики
Измеримость превращает производительность из ощущения в инженерный процесс. Когда команда фиксирует метрики и пороги, обсуждение "быстро или медленно" уходит из субъективной зоны и становится предметом проверяемых фактов.
Ресурсы
Ресурсы вычислительной системы — это ограниченные компоненты, необходимые для выполнения программ.
Основные категории ресурсов:
- процессорное время (CPU time)
- оперативная память (RAM)
- дисковое пространство и операции ввода-вывода
- сетевые ресурсы
- специализированные ресурсы (GPU, TPU)
Ресурсы делятся на:
- вычислительные — процессор, сопроцессоры
- хранилища — оперативная память, дисковое пространство
- коммуникационные — сетевые интерфейсы, шины данных
Что измерять — CPU, память, дисковый I/O, сеть
Метрики производительности — количественные показатели использования ресурсов системы.
Практика показывает, что лучший эффект даёт мониторинг на двух уровнях:
- системные метрики (CPU, RAM, I/O, сеть);
- продуктовые и прикладные метрики (ошибки, p95/p99, время бизнес-операции).
Так можно связать технические признаки с реальным влиянием на пользователя.
| Ресурс | Ключевые метрики | Единицы измерения |
|---|---|---|
| CPU | Использование, время в пользовательском/системном режиме, контекстные переключения | проценты, миллисекунды |
| Память | Используемая память, выделенная память, свопинг, частота сборки мусора | мегабайты, гигабайты |
| Диск | Операции ввода-вывода в секунду (IOPS), пропускная способность, задержка | операции/сек, МБ/с, мс |
| Сеть | Пропускная способность, задержка, количество пакетов, ошибки | Мбит/с, мс, пакеты/с |
Play ITЗагрузка интерактивного демо…
CPU — на что обращать внимание
Процессорное время — основной ресурс для выполнения инструкций программы.
Дополнительно полезно контролировать "шум":
- всплески CPU после релиза;
- долю времени в системном режиме;
- горячие точки по профилировщику на конкретном сценарии.
Важные аспекты анализа CPU:
-
Утилизация процессора
- 0-70% — нормальная нагрузка
- 70-90% — высокая нагрузка, возможны задержки
- 90-100% — критическая нагрузка, риск деградации производительности
-
Режимы выполнения
- Пользовательский режим — выполнение кода приложения
- Системный режим — выполнение системных вызовов ядром ОС Высокий процент системного времени может указывать на чрезмерное количество системных вызовов
-
Контекстные переключения Частые переключения между потоками создают накладные расходы. Норма — до нескольких тысяч переключений в секунду на ядро.
-
Прерывания Аппаратные прерывания от устройств могут конкурировать за процессорное время.
Пример анализа в Linux:
Код ITЗагрузка примера кода…
Пример анализа в Windows через PowerShell:
# Загрузка CPU по процессам
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU
# Системная статистика
Get-Counter '\Processor(_Total)\% Processor Time'
Память — на что обращать внимание
Оперативная память — временно хранилище данных и кода во время выполнения программы.
С точки зрения эксплуатации важна динамика, а не только абсолютное значение. Медленный, но стабильный рост памяти между перезапусками часто сигнализирует об утечке ссылок или о чрезмерном накоплении кэша.
Ключевые метрики памяти:
-
Используемая память Объём памяти, выделенный процессом. Включает:
- кучу (heap) — динамически выделяемая память
- стек (stack) — память для локальных переменных и вызовов
- сегмент кода — исполняемые инструкции
- сегмент данных — глобальные и статические переменные
-
Резидентная память (RSS) Фактически загруженная в физическую память часть процесса.
-
Виртуальная память Общий адресное пространство процесса, включая своп и зарезервированные области.
-
Свопинг Перемещение страниц памяти между оперативной памятью и диском. Частый свопинг указывает на нехватку оперативной памяти.
-
Утечки памяти Постепенный рост используемой памяти без освобождения.
Кэш без ограничения размера — типичный сценарий утечки в управляемых языках:
глобальный кэш := пустой_список
АЛГОРИТМ ДобавитьВКэш()
кусок := выделить_память(10 * 1024 * 1024) // 10 МБ
добавить в кэш кусок // старые элементы не удаляются
КОНЕЦ
АЛГОРИТМ ДобавитьВКэшСЛимитом(макс_элементов)
кусок := выделить_память(10 * 1024 * 1024)
добавить в кэш кусок
если размер(кэш) > макс_элементов то
удалить из кэш самые_старые элементы до размера макс_элементов
конец
КОНЕЦ
Пока на объекты в кэш есть ссылки, сборщик мусора их не освободит — память растёт без остановки.
Справочно на C#
Код ITЗагрузка примера кода…
Справочно на Python (мониторинг выделений)
Код ITЗагрузка примера кода…
Диск — на что обращать внимание
Дисковая подсистема — критический ресурс для операций ввода-вывода.
Важные метрики дисковой подсистемы:
-
IOPS (Input/Output Operations Per Second) Количество операций чтения/записи в секунду. Зависит от типа носителя:
- HDD: 50-200 IOPS
- SATA SSD: 10 000-100 000 IOPS
- NVMe SSD: 100 000-1 000 000+ IOPS
-
Пропускная способность Объём данных, передаваемых в секунду (МБ/с или ГБ/с).
-
Задержка (latency) Время от начала операции до её завершения:
- хороший показатель: < 10 мс
- приемлемый: 10-50 мс
- проблемный: > 50 мс
-
Очереди операций Накопление запросов на диск указывает на перегрузку подсистемы.
Пример анализа дисковой активности в Linux:
Код ITЗагрузка примера кода…
Пример оптимизации дисковых операций:
Код ITЗагрузка примера кода…
Сеть — на что обращать внимание
Сетевые ресурсы — каналы передачи данных между системами.
Ключевые сетевые метрики:
-
Пропускная способность Максимальный объём данных, передаваемых по сети в единицу времени.
-
Задержка (latency) Время прохождения пакета от отправителя к получателю:
- локальная сеть: 0.1-1 мс
- городская сеть: 1-10 мс
- межконтинентальная: 50-200 мс
-
Джиттер (jitter) Вариативность задержки. Высокий джиттер проблематичен для реального времени.
-
Потери пакетов Процент пакетов, не достигших получателя. Приемлемый уровень — < 1%.
-
Количество соединений Ограничение на количество одновременных TCP-соединений.
Пример мониторинга сети в Linux:
Код ITЗагрузка примера кода…
Пример оптимизации сетевых вызовов:
Код ITЗагрузка примера кода…
Метрики кода — cyclomatic complexity, cognitive complexity, coupling, cohesion
Метрики качества кода — количественные показатели структуры и сложности программного кода.
| Метрика | Описание | Идеальное значение |
|---|---|---|
| Цикломатическая сложность | Количество линейно независимых путей выполнения | < 10 на метод |
| Когнитивная сложность | Сложность понимания кода человеком | < 15 на метод |
| Связность (coupling) | Степень зависимости между модулями | Минимальная |
| Связность (cohesion) | Степень объединения функциональности внутри модуля | Максимальная |
| Глубина наследования | Количество уровней в иерархии наследования | < 5 |
| Количество параметров | Аргументы метода | < 5 |
Пример высокой цикломатической сложности:
Код ITЗагрузка примера кода…
Рефакторинг для снижения сложности:
Код ITЗагрузка примера кода…
Профилировщики — CPU profiling, memory profiling, allocation tracking
Профилировщик — инструмент для измерения производительности и потребления ресурсов программой.
Типы профилировщиков:
-
Сэмплинговые профилировщики Периодически снимают состояние стека вызовов. Низкие накладные расходы, но могут пропустить короткие вызовы.
-
Инструментирующие профилировщики Вставляют код измерения в каждый метод. Точны, но создают значительные накладные расходы.
-
Трассировочные профилировщики Записывают последовательность событий выполнения. Подходят для анализа временных зависимостей.
Пример использования профилировщика памяти в .NET:
Код ITЗагрузка примера кода…
Пример использования профилировщика в Java (VisualVM):
// Запуск приложения с агентом профилирования
java -agentpath:/path/to/libprofiler.so=cpu=sample,alloc=5m MyApplication
// Или подключение к работающему процессу через JMX
Разбивка по стеку — attribution of resource usage to call paths
Атрибуция ресурсов по стеку вызовов — распределение потребления ресурсов между различными путями вызовов в программе.
Пример атрибуции памяти:
Выделено 100 МБ:
├─ ProcessOrders() — 60 МБ (60%)
│ ├─ ValidateOrder() — 10 МБ (10%)
│ ├─ CalculateTotal() — 30 МБ (30%)
│ │ └─ ApplyDiscounts() — 25 МБ (25%)
│ └─ SaveOrder() — 20 МБ (20%)
└─ GenerateReport() — 40 МБ (40%)
└─ FormatData() — 35 МБ (35%)
Инструменты для атрибуции:
- async-profiler (JVM) — атрибуция по стеку с низкими накладными расходами
- eBPF (Linux) — системная атрибуция без модификации приложения
- Windows Performance Toolkit — детальная атрибуция для Windows
Пример использования eBPF для атрибуции памяти:
# Трассировка выделений памяти с привязкой к стеку вызовов
bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc { @[ustack()] = count(); }'
Бюджеты производительности — SLA, latency targets
Бюджет производительности — количественное ограничение на время выполнения операции или потребление ресурсов.
Бюджет помогает принимать архитектурные решения заранее. Если лимит p95 известен на старте, проще выбрать формат данных, стратегию кэширования и модель интеграций до появления инцидентов в продакшене.
Типы бюджетов:
-
Временные бюджеты
- время отклика (latency): 95-й перцентиль < 200 мс
- время загрузки страницы: < 3 секунды
- время запуска приложения: < 5 секунд
-
Ресурсные бюджеты
- потребление памяти: < 500 МБ на процесс
- использование CPU: < 30% в среднем
- размер пакета: < 2 МБ
-
Сетевые бюджеты
- количество запросов: < 10 на страницу
- общий размер ресурсов: < 1.5 МБ
Пример определения бюджета в конфигурации:
Код ITЗагрузка примера кода…
Пример мониторинга бюджета в коде:
Код ITЗагрузка примера кода…
Связанные материалы энциклопедии
- Для понимания общей модели выполнения программы — Архитектура выполнения программ
- Для поиска узких мест в вызовах — Вызовы и иерархия
- Для практики оптимизации и профилирования — Производительность и оптимизация
- Для проверки гипотез через отладку и логи — Отладка и видимость состояния
Что запомнить
- Системные метрики и продуктовые метрики работают как единая модель наблюдаемости.
- Одно значение без динамики почти всегда вводит в заблуждение.
- Бюджеты производительности позволяют принимать решения до инцидента.
- Атрибуция по стеку показывает, где именно тратится ресурс.
Типичные ошибки
- Фокус только на среднем времени без p95 и p99.
- Отсутствие порогов и алертов для ключевых метрик.
- Мониторинг только CPU при проблемах, вызванных I/O или сетью.
- Невозможность связать метрики с конкретным бизнес-сценарием.
Мини-практика
- Выберите один важный сценарий пользователя.
- Определите для него latency target и ресурсные лимиты.
- Добавьте измерение p95, ошибок и памяти на этом пути.
- Проверьте поведение при нагрузке и зафиксируйте отклонения от бюджета.