Уже общались по этому поводу в другом чате, но решил еще тут пошарить информацию, так как складывается ощущение что много кто не понимает как работает агрегация в стандартном influxdb backend listener.
На деле стандартный бекенд лисенер по дефолту агрегирует данные не за 5 секунд, как может показаться на первый взгляд, а немного по другому. Лисенер под капотом использует либу DescriptiveStatistics, которая позволяет получать в рантайме разного вида агрегации. Джиметр создает себе несколько датасетов:
- okResponsesStats
- koResponsesStats
- allResponsesStats
- pctResponseStats
По сути датасет это такой себе бакет, куда джиметр будет добавлять респонс таймы, а DescriptiveStatistics будет считать разные агрегации по требованию джиметра, например "koResponsesStats.getPercentile(percentile);"
У каждого датасета есть свой максимальный размер, который можно передать в
jmeter.properties файле.
В
jmeter.properties есть вот такие параметры:
# Backend metrics window mode (fixed=fixed-size window, timed=time boxed)
#backend_metrics_window_mode=fixed
# Backend metrics sliding window size for Percentiles, Min, Max
#backend_metrics_window=100
# Backend metrics sliding window size for Percentiles, Min, Max
# when backend_metrics_window_mode is timed
# Setting this value too high can lead to OOM
#backend_metrics_large_window=5000
Так вот, если максимальный размер датасета к примеру 100 и в него уже добавлено 100 значений, новое значение пойдет перетирать первое в нем и так далее.
А теперь разберем пример:
За первые 5 сек теста джиметр выполнил 2 запроса Login с респонс таймами 100 и 200мс
- okResponsesStats(100,200)
- koResponsesStats()
- allResponsesStats(100,200)
- pctResponseStats(100,200)
при отправке данных джиметр попросит DescriptiveStatistics посчитать avg, pct(90,95,99), min, max. Avg например получится 150мс, что и отправится в инфлюкс
Дальше за вторые 5 сек отправилось еще 3 запроса, один из них свалился, в итоге датасеты выглядят вот так:
- okResponsesStats(100,200,120,160)
- koResponsesStats(190)
- allResponsesStats(100,200,120,160,190)
- pctResponseStats(100,200,120,160,190)
при отправке данных джиметр попросит DescriptiveStatistics посчитать агрегации и либа опять посчитает их на основании всех данных что есть в бакете, то есть avg будет не по (120,160,190) а по всем (100,200,120,160), что тупо с точки зрения мониторинга, так как на графиках в графане я хочу видеть значения среднего как раз за промежутки в 5 сек, а не пересчитывание данных с начала теста.
Для того что б исправить это, нужно изменить значение проперти backend_metrics_window_mode с fixed на timed.
После этого джиметр начнет очищать датасеты okResponsesStats, koResponsesStats, allResponsesStats после каждой отправки данных в инфлюкс, что нам и нужно.
Теперь по поводу персентилей, датасет pctResponseStats не очищается при любых значениях backend_metrics_window_mode, так как персентили нас интересуют не за 5 сек, а за весь тест. Нас интересует последнее значение персентиля для транзакции, которое бекенд лисенер отправляет в инфлюкс. Основная проблема в том что значения не совпадают с тем что показывает джиметр это то что дефолтное значение backend_metrics_window=100, а это значит что 101 и все остальные семплы будут просто начинать перетирать 1,2... значения в pctResponseStats датасете, и в результате в конце теста лисенер посчитает персентиль только за последние 100 семплов. Для того что б значение персентиля было максимально правдивым, нужно поставить в backend_metrics_window большое значение, в идеале больше чем количество семплов что выполняются за тест. При таком раскладе до конца теста pctResponseStats будет в себе хранить все респонс таймы и сможет спокойно посчитать правильный персентиль.
Так что мой совет ставить timed и большие значения в оба backend_metrics_window и backend_metrics_large_window
Ура, но если проверите, то скажете что всеравно не работает, цифры отличаются от того что дает джиметр.
Что я только что протестил для демо: запустил тест на 100 семплов, отсортировал по убыванию респонс таймы и вот мои топ 12 запросов в мс:
155