Управление производительностью: анализ bottlenecks

Bottleneck (узкое место) - это компонент системы, ограничивающий её общую производительность, подобно узкому горлышку бутылки, ограничивающему поток жидкости.

В этой главе мы разберём методику анализа узких мест на примере российского облачного провайдера. Все числа - гипотетические.

Представим гипотетического провайдера с 10000 активных ВМ. Средний чек 8500 ₽/месяц, годовой оборот 1020000000 ₽.

Производительность облачной инфраструктуры это не абстрактная метрика latency. Для облачного провайдера это прямая связь между техническими характеристиками и экономикой бизнеса: каждая миллисекунда задержки это недовольные клиенты, каждое неоптимальное размещение ВМ это потерянная прибыль.

Исследования показывают, что увеличение времени создания ВМ с 30 до 60 секунд снижает конверсию новых клиентов на 15%. При текущей стоимости привлечения клиента (cost per acquisition) 12000 ₽ это означает: - Потеря 180 потенциальных клиентов в месяц. - Дополнительные расходы на маркетинг: 2160000 ₽/месяц. - Или 25920000 ₽ годовых упущенной выгоды

При этом оптимизация, снижающая latency создания ВМ до 20 секунд, потребовала инвестиций в 4800000 ₽ (апгрейд storage backend). Окупаемость 2,2 месяца.

Модель затрат на инфраструктуру

Структура себестоимости облачного провайдера (в год):


| Статья расходов             | Сумма, млн ₽ | Доля      |
| --------------------------- | ------------ | --------- |
| Амортизация оборудования    | 45,6         | 38 %      |
| Электроэнергия и охлаждение | 28,8         | 24 %      |
| Межсетевой трафик           | 14,4         | 12 %      |
| Зарплата инженеров          | 21,6         | 18 %      |
| Прочие операционные         | 9,6          | 8 %       |
| **Итого**                   | **120,0**    | **100 %** |

Каждый процент неэффективности использования CPU это 1200000 ₽ годовых потерь. Каждый лишний гигабайт резервированной под блочные устройства памяти это 86400 ₽/год на электричестве и амортизации.

Методология выявления узких мест

Иерархия анализа

Уровень 1: Инфраструктура (Capacity)
    └── Есть ли свободные ресурсы?

Уровень 2: Распределение (Scheduling)  
    └── Правильно ли распределены нагрузки?

Уровень 3: Конфигурация (Tuning)
    └── Оптимальны ли параметры систем?

Уровень 4: Архитектура (Design)
    └── Соответствует ли архитектура паттернам нагрузки?

Ключевые метрики для облачного провайдера

Compute-уровень:

| Метрика                 | Целевое значение | Критический порог | Стоимость превышения                      |
| ----------------------- | ---------------- | ----------------- | ----------------------------------------- |
| CPU ready time    | < 3 %            | > 10 %            | 450 ₽/час потери производительности на ВМ |
| Steal time              | < 1 %            | > 5 %             | 320 ₽/час компенсации клиентам            |
| Memory ballooning       | < 5 %            | > 20 %            | Риск OOM-kill, репутационные потери       |
| Live migration downtime | < 500 мс         | > 2 с             | 1800 ₽ штраф по SLA за инцидент      
```    |

**Storage-уровень:**

```text
| Метрика             | Целевое значение | Критический порог | Экономический эффект                           |
| ------------------- | ---------------- | ----------------- | ---------------------------------------------- |
| IOPS latency (p99)  | < 10 мс          | > 50 мс           | Потеря 12 % производительности БД-клиентов     |
| Throughput Ceph     | > 800 МБ/с       | < 400 МБ/с        | Необходимость докупки 2 OSD-узлов: 1 440000 ₽ |
| Journal commit time | < 100 мс         | > 500 мс          | Каскадная деградация всего пула                |

Network-уровень:

| Метрика                       | Целевое значение | Критический порог | Последствия                      |
| ----------------------------- | ---------------- | ----------------- | -------------------------------- |
| vSwitch CPU usage             | < 30 %           | > 70 %            | Пакетные потери, переподписка    |
| Overlay encapsulation latency | < 50 мкс         | > 200 мкс         | Деградация микросервисов         |
| BGP convergence               | < 5 с            | > 30 с            | Частичная недоступность регионов |

Практические сценарии анализа

Сценарий: Деградация создания ВМ

Симптомы: - Время создания ВМ выросло с 25 до 180 секунд - 15 % запросов возвращают таймаут - Клиенты массово создают тикеты в поддержку

Фаза 1: Локализация

Используем метод "пяти почему" с количественными данными:

  1. Почему медленно создаются ВМ? → Задержка на стадии "Scheduling"
  2. Почему задержка в Scheduler? → Очередь на обработку достигла 400 запросов
  3. Почему очередь? → Scheduler ждёт ответа от Placement API более 2 секунд
  4. Почему Placement API медленный? → Запросы к БД занимают 1,8 с вместо 50 мс
  5. Почему медленная БД? → Отсутствие индекса по полю availability_zone после миграции

Фаза 2: Количественная оценка

До инцидента: - Пропускная способность: 120 ВМ/мин - Среднее время создания: 25 с

Во время инцидента: - Пропускная способность: 18 ВМ/мин - Среднее время создания: 180 с

Потери: - Отказ от услуг: 340 клиентов × 8500 ₽ = 2890000 ₽/месяц - Компенсации по SLA: 156000 ₽ - Репутационные потери (оценочно): 500000 ₽

Фаза 3: Устранение и предотвращение

Немедленные меры: - Добавление индекса: 15 минут downtime, 0 ₽ - Временное масштабирование Placement API: 3200 ₽/час дополнительных инстансов

Долгосрочные меры: - Внедрение кэширования placement-решений: разработка 180000 ₽, инфраструктура 45000 ₽/месяц - Алерты на latency DB-запросов > 100 мс: настройка 12000 ₽ - Автоматический rollback миграций при деградации метрик: разработка 240000 ₽

Сценарий: Неэффективное использование хранилища

Контекст: Ceph-кластер на 48 OSD-узлов, общая ёмкость 2,4 ПБ.

Обнаружение узкого места:

Анализ heatmap по OSD:

OSD utilization (после rebalance):
┌────────────────────────────────────────┐
│ [████░░░░] OSD-01  45 %  (холодные данные) │
│ [████████] OSD-02  89 %  (перегрузка!)     │
│ [██████░░] OSD-03  67 %                    │
│ [████░░░░] OSD-04  41 %                    │
│ ...                                      │
│ [████████] OSD-23  91 %  (перегрузка!)     │
│ [████░░░░] OSD-24  38 %                    │
└────────────────────────────────────────┘

CRUSH-правила распределяли данные по доменам отказа (стойкам), но не учитывали: - Разную ёмкость дисков (новые узлы с 16 ТБ, старые с 8 ТБ) - Неравномерность нагрузки (некоторые пулы блочные для ВМ, другие объектное хранение архивов)

Экономический расчёт:

Текущая ситуация: - 12 OSD-узлов загружены > 85 % (риск переполнения) - 18 OSD-узлов загружены < 50 % (простой ресурсов) - Эффективная ёмкость: только 67 % от заявленной

Вариант А: Докупка оборудования - 6 новых OSD-узлов: 2160000 ₽ капекс + 324000 ₽/год опекс - Решает проблему на 8 месяцев, затем история повторяется

Вариант Б: Ребалансировка и оптимизация CRUSH - Разработка взвешенных правил: 120000 ₽ - Миграция данных (в рамках maintenance window): 0 ₽ дополнительных - Увеличение эффективной ёмкости до 89 % - Отсрочка капекс на 18 месяцев: экономия 4860000 ₽

Результат: ROI оптимизации = 4050 %

Сценарий: Сетевое замедление в overlay-сети

Симптом: Клиенты жалуются на плавающие задержки между ВМ в одной подсети: от 0,5 мс до 45 мс.

Диагностика:

# Анализ на гипервизоре
$ perf top -p $(pgrep ovs-vswitchd)
  34,20 %  [.] dpif_netdev_execute_actions
  28,50 %  [.] netdev_linux_rxq_recv
  12,80 %  [.] pmd_thread_main

# Проверка PMD (Poll Mode Driver) ядер
$ ovs-appctl dpif-netdev/pmd-rxq-show
  pmd thread numa_id 0 core_id  8: rxq:port-1@q0  45 % usage
  pmd thread numa_id 0 core_id 10: rxq:port-2@q0  89 % usage  ← bottleneck
  pmd thread numa_id 0 core_id 12: rxq:port-3@q0  12 % usage

Причина: Неравномерное распределение очередей RX по PMD-потокам. Порт с наибольшим трафиком (шлюз подсети) привязан к одному ядру, которое работает на пределе.

Варианты решения:

Решение Стоимость Эффект Риски
Добавить PMD-ядра 0 ₽ (использовать резерв) Снижение latency до 2 мс Уменьшение ядер для ВМ
Апгрейд NIC до 2×25 Гбит/с 480000 ₽ (48 узлов) Распределение очередей Простой для замены
Переход на DPDK + hardware offload 1200000 ₽ лицензии + NIC Latency < 0,1 мс Сложность поддержки

Что выбираем: оптимизация распределения очередей (rss-hash) + добавление 2 PMD-ядер. Затраты: 24 часа инженерного времени. Результат: стабильная latency 0,8 мс.

Инструментарий анализа

Профилирование гипервизора

Для KVM/QEMU:

# Анализ CPU-затрат на виртуализацию
$ perf kvm stat live

# Пример вывода:
#  VM-EXIT reason          Samples  Percentage
#  EPT_VIOLATION           45 230    34,5 %
#  EXTERNAL_INTERRUPT      28 150    21,5 %  ← возможно, избыточное прерывание
#  HLT                     22 890    17,5 %
#  IO_INSTRUCTION          18 400    14,1 %

# EPT_VIOLATION — частые промахи TLB, требуется hugepages

Экономика hugepages: - Без hugepages: 5 % CPU на обработку page faults, 120 ВМ на хост - С hugepages (2 МБ): 1,2 % CPU, 145 ВМ на хост - Выигрыш: 25 ВМ × 3200 ₽/месяц = 80000 ₽/месяц на хост - При 200 хостах: 16000000 ₽/год дополнительной выручки без капекс

Анализ Ceph

Команды для выявления узких мест:

# Задержки по операциям
$ ceph osd perf
  osd  commit_latency(ms)  apply_latency(ms)
   0          12                8
  12         145               89   ← аномалия, проверить диск
  24           8                5

# Глубина очереди
$ ceph osd pool stats
  pool vm-volumes
    client io 1,2 ГБ/s wr, 45 MB/s rd
    recovery io 89 MB/s, 12 keys/s
    recovery: 45 % complete
    # Высокий recovery traffic влияет на клиентский IO

Решение: Настройка osd_recovery_max_active = 2 в часы пик, = 8 в ночное время. Снижение влияния recovery на production на 60 %.

Моделирование нагрузки

Стоимость тестового стенда: - Выделенная инфраструктура: 180000 ₽/месяц - Инженерное время на подготовку сценариев: 240000 ₽ (единоразово) - Выявление узкого места до production: бесценно (или 12000000 ₽ стоимость инцидента с 500 клиентами)

Процесс управления производительностью

Цикл непрерывной оптимизации

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  Измерение  │ → │  Анализ     │ → │  Приоритиза │
│  (Collect)  │    │  (Analyze)  │    │  (Prioritize)│
└─────────────┘    └─────────────┘    └──────┬──────┘
       ↑                                      │
       └─────────────┐    ┌───────────────────┘
                     │    ↓
              ┌─────────────┐    ┌─────────────┐
              │  Проверка   │ ← │  Внедрение  │
              │  (Verify)   │    │  (Implement)│
              └─────────────┘    └─────────────┘

Приоритизация по экономическому эффекту

Узкое место Влияние на клиентов Стоимость устранения Эффект в год ROI Приоритет
Деградация storage (p99 > 100 мс) 450 ВМ 360000 ₽ 18000000 ₽ 4900 % P0
Небаланс CPU на хостах 120 ВМ 120000 ₽ 4600000 ₽ 3733 % P1
Лишние сетевые хопы 2000 ВМ 480000 ₽ 8400000 ₽ 1650 % P1
Устаревшие драйверы virtio 80 ВМ 80000 ₽ 960000 ₽ 1 100 % P2
Оптимизация шаблонов ВМ Новые клиенты 240000 ₽ 1200000 ₽ 400 % P3

Команда производительности

Структура команды SRE Performance (штат 5 человек):

Роль Зарплата/мес Фокус
Performance Lead 450000 ₽ Стратегия, приоритизация, коммуникация
Compute Engineer 320000 ₽ CPU, memory, virtualization
Storage Engineer 340000 ₽ Ceph, NVMe, блочные устройства
Network Engineer 330000 ₽ SDN, overlay, физическая сеть
Automation Engineer 280000 ₽ Тестирование, CI/CD для perf

Общий ФОТ: 1720000 ₽/месяц = 20640000 ₽/год

Каждый рубль затрат на команду должен приносить 5–8 ₽ экономии или дополнительной выручки через оптимизацию.

Антипаттерны и ошибки

Оптимизация без измерений

Инженер прочитал о преимуществах io_uring и внедрил его для всех ВМ. Результат — деградация на 15% старых ядер Linux, 3 дня отката, 180000 ₽ потерь.

Любое изменение начинается с канареечного деплоя на 1% ВМ с метриками в реальном времени.

Игнорирование длинного хвоста

Средняя latency 5 мс выглядит отлично. Но если p^99 = 800 мс, 1 % клиентов (в масштабе 10000 ВМ — 100 клиентов) испытывают проблемы. При стоимости привлечения 12000 ₽ и churn rate 20% для недовольных: 100 × 12 000 × 0,2 = 240000 ₽/месяц скрытых потерь.

Оптимизация в вакууме

Уменьшение CPU ready time с 2% до 0,5% техническая победа. Но если для этого понадобилось снизить overcommit ratio с 4:1 до 2:1, вы купили производительность за удвоение инфраструктуры. Стоимость: 45000000 ₽ дополнительных капекс. Возможно, клиенты не заметят разницы между 2% и 0,5%, но денежки вы уже проэтосамили.

Управление производительностью в облачном провайдере это не поиск идеальных цифр в бенчмарках и не красивые слайдики. Это непрерывный торг между: - задержкой и стоимостью - пропускной способностью и надёжностью - капексом и опексом - техническим совершенством и бизнес-ценностью

Каждое узкое место это не проблема, а возможность. Возможность сэкономить миллионы рублей или заработать их, предложив клиенту лучший сервис по той же цене.

Главное правило: измеряйте в рублях, оптимизируйте по приоритету, проверяйте в production.