Сравнение двух версий сервиса показало рост p95 на 8% в одном одинаковом нагрузочном прогоне. Как отличить регрессию производительности от случайного разброса измерений?
Одного прогона недостаточно, чтобы уверенно объявить регрессию. Нужно повторить сравнение в сопоставимых условиях, оценить разброс результатов каждой версии и проверить, выходит ли разница за пределы обычной вариативности измерений.
Для p95 особенно важно анализировать сами наблюдения или распределение результатов нескольких прогонов, а не только сравнивать два итоговых числа. Рост на 8% может быть значимым при стабильных измерениях и случайным шумом при высокой вариативности.
Производительность системы измеряется на фоне множества изменяющихся факторов: состояния кэшей, фоновой активности, планирования потоков, сетевых задержек и состояния зависимостей. Поэтому результат нагрузочного теста является выборочным измерением, а не постоянным свойством сервиса.
Повторные прогоны и статистический анализ появились как практический способ отделить изменение системы от естественного шума эксперимента. Это решает исходную проблему ложных выводов по единичному запуску: команда могла принять случайный всплеск задержки за регрессию или пропустить небольшой, но устойчивый дефект.
Пусть для старой версии p95 составил 200 мс, а для новой — 216 мс. Само различие в 8% не говорит, является ли оно устойчивым: при разбросе результатов от 190 до 220 мс такой эффект может быть обычным шумом, а при стабильных значениях около 200 и 216 мс — свидетельствовать о регрессии.
Неверное решение приводит к лишним откатам, бесполезной оптимизации или выпуску действительно замедлившейся версии. Дополнительный риск возникает, если прогоны отличаются прогревом, составом запросов, объемом данных, лимитами ресурсов или внешней нагрузкой.
Сначала фиксируют условия эксперимента: модель нагрузки, длительность steady state, состав операций, объем и состояние данных, конфигурацию окружения, версии зависимостей и критерии исключения прогонов. После этого каждую версию запускают несколько раз в сопоставимых условиях, желательно чередуя версии, чтобы фоновое изменение среды не было полностью связано с одной из них.
Для каждого прогона сохраняют p95, но не ограничиваются им. Полезно анализировать временной ряд задержек, пропускную способность, долю ошибок и показатели ресурсов. Если p95 меняется от запуска к запуску, оценивают распределение результатов и доверительный интервал разницы; для процентилей часто применяют бутстрэп по подходящим наблюдениям или повторным прогонам.
Регрессия считается убедительной, когда новая версия стабильно показывает худший результат, а оцененный разброс не объясняет наблюдаемую разницу. Порог значимости выбирают с учетом SLA и стоимости ошибки: статистически значимое изменение на 1% может быть практически несущественным, а небольшое, но пересекающее SLA ухудшение — критичным.
Важно не путать статистическую значимость с практической. При большом числе измерений даже малая разница может получить узкий доверительный интервал, но решение должно учитывать абсолютную задержку, бюджет SLA, влияние на пользовательские сценарии и стоимость исправления.
Сравнение должно учитывать множественные проверки. Если команда проверяет десятки метрик и выбирает только случайно ухудшившуюся, вероятность ложной тревоги растет; поэтому заранее определяют основные метрики и правила принятия решения.
После изменения слоя сериализации команда получила p95 216 мс против 200 мс у базовой версии. Вариант принять результат сразу был быстрым, но рискованным: один прогон выполнялся во время фоновой индексации базы данных.
Второй вариант — полностью повторить тест на новой инфраструктуре. Он снижал влияние фоновой нагрузки, но требовал времени и мог скрыть проблемы, зависящие от реального окружения.
Выбрали третий вариант: остановили фоновую задачу, зафиксировали данные и конфигурацию, выполнили по пять чередующихся прогонов каждой версии после прогрева и сравнили распределение p95 вместе с абсолютными задержками. Новая версия стабильно показывала примерно 214–218 мс, базовая — 198–202 мс; разница сохранялась во всех парах прогонов и превышала обычный разброс.
Команда признала результат устойчивой регрессией, дополнительно проверила профилирование сериализации и отменила изменение. Такой вывод был основан не на одном числе, а на повторяемости эффекта и контроле условий эксперимента.
Нет, фиксированного числа прогонов, достаточного для любой системы, не существует. Три прогона могут быть приемлемы для очень стабильного стенда, но недостаточны для высоковариативного окружения или редкого хвоста задержек. Нужно смотреть на разброс, размер эффекта, требуемую точность и последствия ошибки; кроме того, среднее нескольких p95 само по себе не является глобальным p95.
p99 зависит от небольшого числа самых медленных наблюдений и потому особенно чувствителен к случайным событиям: паузам сборщика мусора, сетевым сбоям, вытеснению кэша и фоновой активности. Один выброс может заметно изменить p99, не отражая типичное поведение версии. Нужно проверять повторяемость хвоста, размер выборки, причины экстремальных задержек и, при необходимости, использовать доверительные интервалы или сравнение распределений.
Пересечение интервалов не является универсальным доказательством отсутствия различия, особенно если интервалы построены отдельно и разными методами. Правильнее оценивать интервал непосредственно для разницы между версиями, сохраняя парность сопоставимых прогонов или наблюдений, и заранее определить минимально важный эффект. Если неопределенность все еще велика, увеличивают число контролируемых прогонов, уменьшают шум эксперимента или формулируют вывод как недостаточно подтвержденный, а не как доказанное отсутствие регрессии.