Перейти к основному содержимому

Ресурсопотребление и метрики

Разработчику Архитектору Инженеру

Ресурсопотребление и метрики

Измеримость превращает производительность из ощущения в инженерный процесс. Когда команда фиксирует метрики и пороги, обсуждение "быстро или медленно" уходит из субъективной зоны и становится предметом проверяемых фактов.


Ресурсы

Ресурсы вычислительной системы — это ограниченные компоненты, необходимые для выполнения программ.

Основные категории ресурсов:

  • процессорное время (CPU time)
  • оперативная память (RAM)
  • дисковое пространство и операции ввода-вывода
  • сетевые ресурсы
  • специализированные ресурсы (GPU, TPU)

Ресурсы делятся на:

  • вычислительные — процессор, сопроцессоры
  • хранилища — оперативная память, дисковое пространство
  • коммуникационные — сетевые интерфейсы, шины данных

Что измерять — CPU, память, дисковый I/O, сеть

Метрики производительности — количественные показатели использования ресурсов системы.

Практика показывает, что лучший эффект даёт мониторинг на двух уровнях:

  • системные метрики (CPU, RAM, I/O, сеть);
  • продуктовые и прикладные метрики (ошибки, p95/p99, время бизнес-операции).

Так можно связать технические признаки с реальным влиянием на пользователя.

РесурсКлючевые метрикиЕдиницы измерения
CPUИспользование, время в пользовательском/системном режиме, контекстные переключенияпроценты, миллисекунды
ПамятьИспользуемая память, выделенная память, свопинг, частота сборки мусорамегабайты, гигабайты
ДискОперации ввода-вывода в секунду (IOPS), пропускная способность, задержкаоперации/сек, МБ/с, мс
СетьПропускная способность, задержка, количество пакетов, ошибкиМбит/с, мс, пакеты/с

Play ITЗагрузка интерактивного демо…


CPU — на что обращать внимание

Процессорное время — основной ресурс для выполнения инструкций программы.

Дополнительно полезно контролировать "шум":

  • всплески CPU после релиза;
  • долю времени в системном режиме;
  • горячие точки по профилировщику на конкретном сценарии.

Важные аспекты анализа CPU:

  1. Утилизация процессора

    • 0-70% — нормальная нагрузка
    • 70-90% — высокая нагрузка, возможны задержки
    • 90-100% — критическая нагрузка, риск деградации производительности
  2. Режимы выполнения

    • Пользовательский режим — выполнение кода приложения
    • Системный режим — выполнение системных вызовов ядром ОС Высокий процент системного времени может указывать на чрезмерное количество системных вызовов
  3. Контекстные переключения Частые переключения между потоками создают накладные расходы. Норма — до нескольких тысяч переключений в секунду на ядро.

  4. Прерывания Аппаратные прерывания от устройств могут конкурировать за процессорное время.

Пример анализа в Linux:

Код ITЗагрузка примера кода…

Пример анализа в Windows через PowerShell:

# Загрузка CPU по процессам
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU

# Системная статистика
Get-Counter '\Processor(_Total)\% Processor Time'

Память — на что обращать внимание

Оперативная память — временно хранилище данных и кода во время выполнения программы.

С точки зрения эксплуатации важна динамика, а не только абсолютное значение. Медленный, но стабильный рост памяти между перезапусками часто сигнализирует об утечке ссылок или о чрезмерном накоплении кэша.

Ключевые метрики памяти:

  1. Используемая память Объём памяти, выделенный процессом. Включает:

    • кучу (heap) — динамически выделяемая память
    • стек (stack) — память для локальных переменных и вызовов
    • сегмент кода — исполняемые инструкции
    • сегмент данных — глобальные и статические переменные
  2. Резидентная память (RSS) Фактически загруженная в физическую память часть процесса.

  3. Виртуальная память Общий адресное пространство процесса, включая своп и зарезервированные области.

  4. Свопинг Перемещение страниц памяти между оперативной памятью и диском. Частый свопинг указывает на нехватку оперативной памяти.

  5. Утечки памяти Постепенный рост используемой памяти без освобождения.

Кэш без ограничения размера — типичный сценарий утечки в управляемых языках:

глобальный кэш := пустой_список

АЛГОРИТМ ДобавитьВКэш()
кусок := выделить_память(10 * 1024 * 1024) // 10 МБ
добавить в кэш кусок // старые элементы не удаляются
КОНЕЦ

АЛГОРИТМ ДобавитьВКэшСЛимитом(макс_элементов)
кусок := выделить_память(10 * 1024 * 1024)
добавить в кэш кусок
если размер(кэш) > макс_элементов то
удалить из кэш самые_старые элементы до размера макс_элементов
конец
КОНЕЦ

Пока на объекты в кэш есть ссылки, сборщик мусора их не освободит — память растёт без остановки.

Справочно на C#

Код ITЗагрузка примера кода…

Справочно на Python (мониторинг выделений)

Код ITЗагрузка примера кода…


Диск — на что обращать внимание

Дисковая подсистема — критический ресурс для операций ввода-вывода.

Важные метрики дисковой подсистемы:

  1. 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
  2. Пропускная способность Объём данных, передаваемых в секунду (МБ/с или ГБ/с).

  3. Задержка (latency) Время от начала операции до её завершения:

    • хороший показатель: < 10 мс
    • приемлемый: 10-50 мс
    • проблемный: > 50 мс
  4. Очереди операций Накопление запросов на диск указывает на перегрузку подсистемы.

Пример анализа дисковой активности в Linux:

Код ITЗагрузка примера кода…

Пример оптимизации дисковых операций:

Код ITЗагрузка примера кода…


Сеть — на что обращать внимание

Сетевые ресурсы — каналы передачи данных между системами.

Ключевые сетевые метрики:

  1. Пропускная способность Максимальный объём данных, передаваемых по сети в единицу времени.

  2. Задержка (latency) Время прохождения пакета от отправителя к получателю:

    • локальная сеть: 0.1-1 мс
    • городская сеть: 1-10 мс
    • межконтинентальная: 50-200 мс
  3. Джиттер (jitter) Вариативность задержки. Высокий джиттер проблематичен для реального времени.

  4. Потери пакетов Процент пакетов, не достигших получателя. Приемлемый уровень — < 1%.

  5. Количество соединений Ограничение на количество одновременных TCP-соединений.

Пример мониторинга сети в Linux:

Код ITЗагрузка примера кода…

Пример оптимизации сетевых вызовов:

Код ITЗагрузка примера кода…


Метрики кода — cyclomatic complexity, cognitive complexity, coupling, cohesion

Метрики качества кода — количественные показатели структуры и сложности программного кода.

МетрикаОписаниеИдеальное значение
Цикломатическая сложностьКоличество линейно независимых путей выполнения< 10 на метод
Когнитивная сложностьСложность понимания кода человеком< 15 на метод
Связность (coupling)Степень зависимости между модулямиМинимальная
Связность (cohesion)Степень объединения функциональности внутри модуляМаксимальная
Глубина наследованияКоличество уровней в иерархии наследования< 5
Количество параметровАргументы метода< 5

Пример высокой цикломатической сложности:

Код ITЗагрузка примера кода…

Рефакторинг для снижения сложности:

Код ITЗагрузка примера кода…


Профилировщики — CPU profiling, memory profiling, allocation tracking

Профилировщик — инструмент для измерения производительности и потребления ресурсов программой.

Типы профилировщиков:

  1. Сэмплинговые профилировщики Периодически снимают состояние стека вызовов. Низкие накладные расходы, но могут пропустить короткие вызовы.

  2. Инструментирующие профилировщики Вставляют код измерения в каждый метод. Точны, но создают значительные накладные расходы.

  3. Трассировочные профилировщики Записывают последовательность событий выполнения. Подходят для анализа временных зависимостей.

Пример использования профилировщика памяти в .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 известен на старте, проще выбрать формат данных, стратегию кэширования и модель интеграций до появления инцидентов в продакшене.

Типы бюджетов:

  1. Временные бюджеты

    • время отклика (latency): 95-й перцентиль < 200 мс
    • время загрузки страницы: < 3 секунды
    • время запуска приложения: < 5 секунд
  2. Ресурсные бюджеты

    • потребление памяти: < 500 МБ на процесс
    • использование CPU: < 30% в среднем
    • размер пакета: < 2 МБ
  3. Сетевые бюджеты

    • количество запросов: < 10 на страницу
    • общий размер ресурсов: < 1.5 МБ

Пример определения бюджета в конфигурации:

Код ITЗагрузка примера кода…

Пример мониторинга бюджета в коде:

Код ITЗагрузка примера кода…


Связанные материалы энциклопедии


Что запомнить

  • Системные метрики и продуктовые метрики работают как единая модель наблюдаемости.
  • Одно значение без динамики почти всегда вводит в заблуждение.
  • Бюджеты производительности позволяют принимать решения до инцидента.
  • Атрибуция по стеку показывает, где именно тратится ресурс.

Типичные ошибки

  • Фокус только на среднем времени без p95 и p99.
  • Отсутствие порогов и алертов для ключевых метрик.
  • Мониторинг только CPU при проблемах, вызванных I/O или сетью.
  • Невозможность связать метрики с конкретным бизнес-сценарием.

Мини-практика

  1. Выберите один важный сценарий пользователя.
  2. Определите для него latency target и ресурсные лимиты.
  3. Добавьте измерение p95, ошибок и памяти на этом пути.
  4. Проверьте поведение при нагрузке и зафиксируйте отклонения от бюджета.