Замеры производительности, сбор статистики и персентили

В low-latency торговых системах важна не средняя оценка jitter/latency, а оценка в персентилях. Значения задержек по персентилям является важным показателем скорости работы вашей торговой системы. Почему? Для начала, что такое персентиль? Это понятие из статистики, которое объяснено в Википедии вполне точно.

Если, скажем, наша система из 1000 событий 999 событий обрабатывает за 1 секунду каждое, а какое-то одно за 100 секунд, наше среднее арифметическое значение latency составит 1,099 секунды ([999х1 + 1х100]/1000). Но в реальной жизни это значение не имеет никакого смысла, как и средняя температура по больнице или средняя зарплата по стране.

Что толку, если система 999 событий отработает за 1 секунду, если как раз именно на обработку самого важного и самого критического события у нее уйдет целых 100 секунд, по прошествии которых результат уже будет никому не нужен? Эмпирически, например, мы знаем в случае статистического арбитража шанс выгодного ордера выпадает 1 на миллион. Значит, если ваша система 999.999 событий обрабатывает за 1 микросекунду, а над одним событием из миллиона задумывается на 10 секунду, latency такой системы считается неприемлемым. Как это все измерить и выразить в цифрах?

Как производится замер?

Для начала на тестовом стенде тестируем нашу систему определенное время, пропуская через нее определенное количество сообщений, скажем, миллион. Количество сообщений должно быть близко к тому, сколько сообщений вы ожидаете получить за этот же период во время реального торгового дня.

Замеряем, сколько времени занимает прохождение каждого сообщения от входа до выхода. Этот показатель называется internal latency, т.е. время реакции вашей системы на входящее событие, время требуемое вашей системой на обработку и выдачу конечного результата. Если internal latency для всех сообщений — постоянное число, скажем, 1 миллисекунда, мы смело можем взять это значение и гордиться им (или стремиться улучшить, если оно не совпадает с нашим ожиданием).

jitter00

Но скорей всего internal latency сообщений будет разным: какое-то сообщение пройдет через систему быстрее, какое-то медленнее. И эти значения взятые все вместе образуют некий разброс вокруг какого-то общего значения. Например, вы обнаружите, что большинство сообщений прошли через систему за ожидаемые 990~999 микросекунд, а небольшое их число — за 200 микросекунд, а некоторые сообщения прошли через систему за 5-6 миллисекунд! Эти всплески latency называются jitter (дословно дребезг). На графике они выглядят как неожиданные всплески/пики или провалы, выбивающиеся из общего ряда обычных значений.

jitter01

Разброс значений от среднего может быть несимметричным. Большая часть значений (например, 999.000 сообщений из миллиона), скажем, укладывается в +/- одно стандартное распределение, а 1000 значений выходят за все мыслимые пределы.

Более того, распределение всплесков может быть совершенно неожиданным. Например, эти всплески могут появляться на графике через определенные интервалы, или, например, группироваться друг с другом на определенном участке графика.

jitter02

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

jitter01

Как считать?

Для визуальной простоты: сортируем все значения latency по ранжиру, а потом делаем делаем выборку: минимум, максимум, 50%, 75%, 90%, 95%, 99%.

Второе большое значение после самого большое значения из 100 даст нам значение 99-ого персентиля, 99.9% — 1 сообщение из 1.000, 99,99% — 1 сообщение из 10.000, и 99,999% — 1 сообщение из 100.000, а для некоторых случаев требуется знать даже 99,9999% — 1 сообщение из 1.000.000. Т.е. для оценки latency с персентилем 99,9999% вам надо пропустить через систему 1.000.000 сообщений и вторая самая долгая обработка одного сообщения из миллиона даст вам персентиль 99,9999%.

Ниже представлен пример графика построенного по результатам замера производительности некоей системы под разными нагрузками. Вертикальная шкала графика — логарифмическая. На графике видно, что при нагрузке в 125 тысяч (первая тёмно-синяя линия) сообщений, 90% сообщений обрабатываются менее чем за 1 микросекунду. 99.9% сообщений — менее чем за 5 микросекунд, 99.99% сообщений — менее чем за 50 микросекунд. По мере роста нагрузки, график latency меняется. При нагрузке в 7 миллионов сообщений 90% из них обрабатываются уже менее чем за 1000 микросекунд, т.е. за 1 миллисекунду, а крайние значения (99.999%) уже достигают 2-3 миллисекунд! Данные графики наглядно показывают, где у вашей системы находится «sweet spot», после которой ее производительность резко просаживается.

Для low-latency систем оценку смотрят начиная с 95%. Для ultra-low latency систем оценку сморят начиная с 99,99%. То есть ваша торговая система будет считаться ultra-low latency системой, если обработка 99,99% ваших сообщений занимает меньше 100 микросекунд. Конечно, все очень сильно зависит от рынка,  с которым работает ваша система и инструментами. Например, на рынке Forex может потребоваться latency меньше 10 микросекунд.

Выводы

В данной статье я привел пример того, каким способом измеряется и выражается производительность low-latency системы. Когда в очередной раз на форумах, в разговорах, в презентациях вам будут расхваливать latency того или иного продукта и сравнивать его с «медленными» конкурентами, или когда менеджмент будет требовать от вашей системы определенного значения latency, вы будете знать, какой вопрос должен быть первым: «При какой нагрузке и на каком персентиле?«

См. также

3 комментария на “Замеры производительности, сбор статистики и персентили

  1. moviefoor

    Хорошие статьи. Расскажите пожалуйста как корректно выполнить измерение времени, что бы исключить внешние факторы. Как собирать метрики с системы?

    Нравится

    1. alexkachanov Автор записи

      на разных уровнях замеры делаются по-разному. Например, вот Шипилёв рассказывает о micro-бенчмаркинге: https://www.youtube.com/watch?v=8pMfUopQ9Es «Алексей Шипилёв — Java Benchmarking: как два таймстампа прочитать!» то есть здесь измерения производятся на уровне вызова методов и отдельных блоков кода. А в этой статье — https://algodma.wordpress.com/2020/11/05/%d1%87%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-tick-to-trade-%d0%b8-%d0%ba%d0%b0%d0%ba-%d0%b5%d0%b5-%d0%bc%d0%b5%d1%80%d1%8f%d1%82%d1%8c/ я рассказываю как замерять внешнюю latency — т.е. всю систему в целом. Иногда бывает так что как раз внешние факторы исключать и не следует. потому что на PROD даже самый вылизанный код может лагать из-за этих самых внешних факторов

      Нравится

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s