awesome-everything EN
↑ Обратно к восхождению

Наблюдаемость

Sampling vs instrumentation profiling: почему 99 Гц побеждает в production

Суть Instrumentation оборачивает каждый вызов функции — точные данные, но коллапсирует под нагрузкой; sampling захватывает один стек каждые 10 мс при ограниченном overhead, что делает его единственно жизнеспособным подходом в production.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 13 min

На staging-сервере profiling работает без проблем. Тот же profiler в production поднимает latency на 40%. Profiler не менялся — поменялась нагрузка. Понять почему — разница между инструментом, который можно держать включённым always, и тем, который используешь только в экстренных случаях.

Два способа профилировать

Instrumentation profiling оборачивает каждый вход и выход функции таймирующим кодом. Runtime измеряет точное число вызовов и точную длительность каждой функции. Стоимость пропорциональна частоте вызовов — при 10 миллионах вызовов в секунду платишь за 10 миллионов замеров в секунду. На dev-машине с лёгкой нагрузкой это нормально; под production-трафиком может добавить 20-100% overhead. Instrumentation хороша для маленьких изолированных benchmark’ов; для always-on production profiling не годится.

Sampling profiling работает иначе: внешний таймер срабатывает N раз в секунду и захватывает текущий call stack. Стоимость ровно N stack walk’ов в секунду — независимо от того, сколько вызовов функций происходит между ними. При 100 Гц — это 100 stack walk’ов в секунду, каждый стоит ~5-20 микросекунд, итого overhead ~0.5-2% на занятом CPU. Современные profiler’ы (Go pprof, Linux perf, Java async-profiler, py-spy, eBPF-профилеры) — все sampling-based. Стоимость ограничена.

Ключевое статистическое свойство

При sample rate R Гц функция, потребляющая X% CPU, будет появляться в X% сэмплов — независимо от числа вызовов. Статистика — «доля CPU-времени», не «счётчик вызовов». Это именно та метрика, нужная для поиска узких мест: хочешь знать, какая функция чаще всего на CPU, а не какую чаще всего вызывают.

Следствие: sampling при 100 Гц достаточен для обнаружения функций, потребляющих больше нескольких процентов CPU. Функция, использующая 10% CPU, будет попадать в ~10 сэмплов в секунду. За 30-секундный профиль — 300 сэмплов — вполне достаточно для надёжной оценки.

Выбор sample rate на практике

Linux perf по умолчанию 99 Гц — не 100 Гц. Это намеренно: 100 Гц может случайно синхронизироваться с периодическими kernel-таймерами и давать вводящие в заблуждение результаты. 99 Гц избегает резонанса. Go pprof по умолчанию 100 Гц. eBPF-based continuous profiler’ы обычно используют 19 или 49 Гц для минимизации влияния на очень занятые контейнеры.

ПодходМодель стоимостиТипичный overheadПрименение
InstrumentationНа вызов функции20-100%Dev benchmark’и, целевые micro-benchmark’и
Sampling (Go pprof)На сэмпл (100/с)0.5-2%Production on-demand или continuous
Sampling (eBPF)На сэмпл (19-49/с)1-3%Continuous, polyglot-флоты
Continuous profiler (полный)Sampling + batching + shipping2-5%Always-on production fleet
Sample rate'ы и overhead
Go pprof дефолтный sample rate
100 Гц
Linux perf дефолтный rate
99 Гц (избегает синхронизации с таймером)
eBPF profiler типичный rate
19 или 49 Гц
Стоимость stack walk на сэмпл
~5-20 мкс
Overhead при 100 Гц, занятый CPU
~0.5-2%
Continuous profiler (полный pipeline)
2-5% CPU

Когда заявленный 2-5% overhead становится 12%

Continuous profiler заявляет 2% overhead; ты измеряешь 12% в production. Частые причины:

  • Sample rate случайно выставлен в 10 раз выше дефолта.
  • Stack walking дорог, потому что язык использует JIT и требует symbol resolution при каждом сэмпле (Python, JVM без native hooks).
  • Agent делает тяжёлую компрессию или декомпрессию символов в application thread вместо async.
  • Средняя глубина стека 120+ frames (глубокие middleware-цепочки) — каждый сэмпл пропорционально дороже.

Прежде чем обвинять инструмент — проверь конфигурацию.

Викторина

Сервис совершает 5 миллионов вызовов функций в секунду. Instrumentation profiler добавляет 1 мкс на вызов. Sampling profiler работает при 100 Гц и стоит 10 мкс на сэмпл. Какой добавляет меньше overhead?

Викторина

Linux perf по умолчанию 99 Гц, а не 100 Гц. Почему?

Вспомните перед уходом
  1. 01
    Почему instrumentation profiling непрактичен для always-on production profiling?
  2. 02
    Sampling profiler сообщает, что функция присутствует в 8% сэмплов. Что это значит с точки зрения CPU?
  3. 03
    Почему Linux perf использует 99 Гц вместо 100 Гц?
Итог

Instrumentation profiling оборачивает каждый вызов функции, давая точные данные, но коллапсируя под production-нагрузкой при масштабировании overhead с частотой вызовов. Sampling profiling срабатывает N раз в секунду и захватывает текущий стек — ограниченный overhead независимо от числа вызовов между сэмплами. При 100 Гц и ~10 мкс на stack walk overhead 0.5-2%; полный continuous profiler pipeline (с batching и shipping) — 2-5%. Статистическое свойство, делающее sampling мощным: функция, потребляющая X% CPU, появляется в X% сэмплов — оценки доли CPU без затрагивания каждого вызова. Linux perf по умолчанию 99 Гц для избегания синхронизации с периодическими kernel-таймерами — тонкая деталь корректности, которую должен знать каждый senior-инженер.

Связанные уроки
встречается в167
Продолжить восхождение ↑Типы профилей: CPU, память, off-CPU, mutex — какой когда брать
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.