Дебаг бенчмарков — то, чем я занимаюсь много лет, и я повидал поразительное и местами комичное разнообразие способов, которыми бенчмарки идут не так. Проблема в том, что бенчмарк-инструменты часто запускают, не понимая, что именно они тестируют, и не проверяя, что результаты валидны. Это ведёт к плохим архитектурным и продуктовым решениям, которые потом преследуют команду годами.
Доверять цифрам только потому, что тула выдала цифры — главная ошибка бенчмаркинга. На вашей машине запустилась команда, на экране нарисовался график — это не значит, что вы измерили то, что хотели.
Что такое active benchmarking
Active benchmarking — это методика, при которой пока тест идёт, вы активно наблюдаете систему: смотрите на метрики ОС, профилируете процессы, инспектируете latency, смотрите на флеймграфы. Цель — доказать, что бенчмарк действительно меряет то, что вы предположили.
Противоположность — passive benchmarking: «запустил тулу, скопировал число из вывода, нарисовал слайд». Подавляющее большинство опубликованных бенчмарков — пассивные. И в подавляющем большинстве из них есть проблема, незамеченная автором.
Что обычно идёт не так
1. Вы измеряете не то, что думаете
Классика: бенчмарк сети между двумя серверами выдаёт 200 Мбит/с. Кто-то делает вывод, что сеть медленная. На самом деле это была производительность инструмента (одного потока iperf), а сеть свободно пропускает 10 Гбит/с при правильной нагрузке.
Правило: пока бенчмарк работает, проверьте, упирается ли он действительно в то, что вы тестируете. Если тестируете CPU — посмотрите, что CPU действительно занят на 100%. Если диск — что IOPS реально упёрся в потолок устройства, а не в ограничение приложения.
2. Бенчмарк ограничен чем-то невидимым
-
Single-threaded инструмент тестирует параллельную систему.
-
Локальный диск-IO упирается в page cache, а не в реальный SSD.
-
TCP-окно слишком маленькое для long-fat сети.
-
Network bandwidth ограничен NIC offloading, а не link speed.
Каждый из этих случаев даёт «реалистично выглядящий» результат, который не отражает реальный потолок.
3. Warm-up и steady state
Первые секунды любого бенчмарка — это разогрев: JIT-компиляция, заполнение кэшей, инициализация пулов соединений. Если ваш бенчмарк короткий, вы измеряете в основном разогрев. Active benchmarking подразумевает: «запустить, дождаться steady state, потом начать измерения».
4. Coordinated omission
Классическая ловушка load-тестов: когда сервер тормозит, клиент ждёт ответа и не отправляет следующий запрос. В результате latency-гистограмма выглядит хорошо — потому что медленные запросы, которые должны были быть отправлены в эту секунду, просто не были отправлены. Реальная latency, которую увидит юзер в продакшене, намного хуже.
Лечится HdrHistogram с компенсацией coordinated omission или использованием тулзы с открытой моделью нагрузки (open loop — например, wrk2).
Practical workflow
Шаг 1: сформулируйте гипотезу
Прежде чем запускать бенчмарк, ответьте себе:
-
Что именно я хочу узнать? («Способна ли база выдержать 50K RPS чтения с этим железом?»)
-
Какие компоненты системы должны быть бутылочным горлышком в этом тесте? («БД CPU, не сеть, не диск».)
-
Какой результат я ожидаю и почему?
Если вы не можете назвать ожидание — вы не понимаете, что тестируете.
Шаг 2: подготовьте observability
Запустите параллельно с бенчмарком:
-
vmstat 1/pidstat 1— общая картина CPU, IO, контекст-свитчей. -
iostat -x 1— диск. -
sar -n DEV 1илиnload— сеть. -
perf stat -aилиperf top— что именно жрёт CPU. -
Для конкретного процесса — flamegraph (Brendan Gregg’s own tool: FlameGraph).
-
dstat,nicstat,tiptop,lsof,tcpdump— по необходимости.
Шаг 3: запустите бенчмарк, держа observability открытым
Во время теста смотрите на метрики. Сверяйте с гипотезой:
-
«Я думал, БД должна быть CPU-bound. Покажет ли
top100% на её PID?» -
«Я думал, мы упрёмся в диск. Покажет ли
iostatdevice utilization 100%?» -
«Я думал, network должна быть свободна.
sar -n DEVпоказывает <10% — да, как и ожидалось.»
Если реальность не соответствует гипотезе — либо ваша гипотеза неправильная (полезно узнать), либо ваш бенчмарк меряет не то (тоже полезно узнать).
Шаг 4: разоблачите тулзу
Каждый бенчмарк-инструмент имеет ограничения. Прежде чем доверять цифре, изучите:
-
Single-threaded или multi-threaded?
-
Open или closed loop по нагрузке?
-
Как считается latency — wall-clock или CPU?
-
Что инструмент не учитывает (пример:
iperfне учитывает TCP retransmits)?
Лучшие тулзы (fio, wrk2, sysbench с правильными опциями) дают достоверные цифры. Многие popular-тулзы — нет.
Главное
Бенчмарк без active observability — это анекдот, выдающий себя за данные. Если вы не можете во время теста показать, почему система упирается именно туда, куда упирается, ваш результат может быть просто артефактом инструмента, кэша, или пиковой неудачи. Лучшая защита — методичность: гипотеза → observability на месте → тест → сверка → выводы.
Эта методика — не теоретическая. В Netflix мы её ежедневно применяли, когда выясняли, почему продакшен-инстанс EC2 показывает другую производительность, чем dev-машина. Раз за разом оказывалось: ответ не в железе, а в неточно понятых ограничениях бенчмарка.