Урок по треку Наблюдаемость и SRE 7 мин

Производительность и профилирование в проде за 7 минут

Перцентили и хвостовые задержки, методика поиска узкого места, flame graph, профилирование в проде и eBPF.

«Тормозит» это не диагноз. Задача инженера пройти от симптома (вырос p99) к конкретной причине (функция сериализации тратит 40% CPU, или 80 запросов в базу вместо одного) и подтвердить её измерением, а не догадкой.

Перцентили и хвост

  • Распределение задержек почти всегда с длинным хвостом: p50 говорит о типичном запросе, p99 и p99.9 о худших, которые и запоминают пользователи.
  • Усиление хвоста: если страница делает 100 параллельных вызовов, и каждый в 1% случаев медленный, то хотя бы один медленный будет в 1 - 0.99^100 ≈ 63% загрузок страницы. Поэтому у бэкендов с широким разветвлением p99 важнее p50.
  • Борьба с хвостом: таймауты и дедлайны, хеджированные запросы (повторный запрос к другой реплике, если первый не ответил за p95), ограничение очередей, вынос тяжёлой работы из горячего пути.

Методика

  1. Симптом: какой SLI ухудшился, с какого времени, для каких запросов (RED).
  2. Где время: трейсы медленных запросов, собственное время спанов против ожидания зависимостей.
  3. Ресурсы: USE по CPU, памяти, диску, сети и по программным ресурсам (пулы соединений, потоки, блокировки).
  4. Профиль: если время уходит внутри сервиса, профилировщик покажет, на какие функции.
  5. Гипотеза и проверка: изменить одно, измерить снова.

Классика Брендана Грегга для Linux-узла за первые минуты: uptime (load average), dmesg | tail (OOM, ошибки), vmstat 1, mpstat -P ALL 1, pidstat 1, iostat -xz 1, free -m, sar -n DEV 1, sar -n TCP,ETCP 1, top.

Профилировщики

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

  • Go: net/http/pprof, go tool pprof http://host/debug/pprof/profile?seconds=30; профили CPU, heap, goroutine, mutex, block.
  • Java: async-profiler, Java Flight Recorder (JFR).
  • Python: py-spy подключается к работающему процессу без перезапуска: py-spy top --pid, py-spy record -o profile.svg --pid.
  • Node.js: --cpu-prof, инспектор, clinic.js.
  • Linux в целом: perf record -g и perf report, eBPF-инструменты (bpftrace, BCC: runqlat, biolatency, offcputime).

Непрерывное профилирование (Grafana Pyroscope, Parca) постоянно снимает профили со всех экземпляров с малыми накладными расходами. Можно сравнить профиль до и после релиза и найти регрессию.

Flame graph

Визуализация стеков: каждый прямоугольник это функция, по вертикали глубина стека (вызывающая ниже, вызываемая выше), ширина это доля сэмплов, в которых функция была на стеке. Ось X не время: функции на одном уровне отсортированы по алфавиту. Ищут широкие «плато» наверху: функции, которые сами тратят много времени.

  • On-CPU профиль показывает, где сжигается процессор.
  • Off-CPU показывает, где поток ждёт: блокировки, ввод-вывод, сон. Если сервис медленный, а CPU почти не загружен, нужен именно off-CPU анализ или трейсы.

Частые причины медленности

  • N+1 запросов к базе в цикле.
  • Ожидание пула: соединений к базе меньше, чем одновременных запросов (закон Литтла).
  • Троттлинг CPU в контейнере: лимит CPU исчерпан внутри периода квоты, процесс замораживается до следующего периода. Средняя загрузка низкая, а задержки большие. Метрика container_cpu_cfs_throttled_periods_total.
  • Паузы сборщика мусора и избыточные аллокации.
  • Блокировки (mutex contention) и последовательная работа там, где можно параллельно.
  • Сериализация больших JSON, регулярные выражения с катастрофическим перебором.
  • Синхронные вызовы медленных зависимостей без таймаутов.

Закон Амдала

Если долю p работы можно распараллелить на n потоков, ускорение не больше 1 / ((1 - p) + p / n). При p = 0.9 и 10 потоках ускорение около 5.3, а не 10: последовательная часть ограничивает всё. Поэтому оптимизировать надо самое широкое место профиля, а не то, что проще.

Осторожно в проде

  • strace на горячем процессе может замедлить его в разы (он работает через ptrace). eBPF-инструменты и perf гораздо безопаснее.
  • Дамп кучи большого JVM-процесса останавливает его на секунды и пишет гигабайты.
  • Профилируйте один экземпляр, выведя его из ротации, если сомневаетесь.

Частые ошибки

  • Оптимизировать «на глаз» без профиля.
  • Смотреть только на средние задержки.
  • Считать, что раз CPU 30%, проблема не в CPU (троттлинг, один перегруженный поток).
  • Читать ось X flame graph как время.
  • Бенчмарк на ноутбуке вместо профиля прода.

Что спросят на собесе

  • Сервис стал медленнее после релиза: как будете искать.
  • Как читать flame graph.
  • Что такое on-CPU и off-CPU профилирование.
  • Почему p99 важнее среднего и что такое усиление хвоста.
  • Что такое CPU throttling в Kubernetes и как его увидеть.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.