Перейти к основному содержимому
Нормативная версия документации - английская

Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.

Методология

Как ruststream-fred измеряет себя: три цикла, прогон на настоящем сервере Redis, арифметика «упирается в брокер» и подсчёт кода. Процедура общая для всего фреймворка (методология RustStream), а эта страница говорит, как она выглядит на Redis.

Три цикла​

Один процесс прогоняет каждый сценарий трижды, тремя циклами, которые различаются одним: тем, что передаёт сообщения.

  • Сырой клиент. Цикл на fred: прочитать, декодировать, подтвердить.
  • Крейт брокера. Этот крейт и ничего над ним: брокер подключается, дескриптор создаёт подписку, а цикл забирает доставки из её потока, декодирует и подтверждает их.
  • RustStream. Сервис, который пишет пользователь: обработчик #[subscriber] и приложение вокруг него.

Всё остальное в трёх циклах одинаково: пул и его размер, группа потребителей и имя потребителя, команды чтения с их COUNT и BLOCK, место подтверждения, декодирование в тот же тип, байты полезной нагрузки, рантайм tokio с четырьмя рабочими потоками и бинарник. Все три цикла получают сообщения от одного и того же издателя на fred, который отправляет команды конвейером, поэтому различия между циклами лежат на стороне потребления.

Тело сообщения - 512 байт JSON.

Прогон​

  • Число сообщений даёт пробный замер скорости сырого цикла, поэтому измеряемый прогон на любой машине длится не меньше пяти секунд.
  • Окно открывается на первой доставке и закрывается, когда забрана последняя, во всех трёх циклах.
  • Циклы чередуются: сырой, крейт, RustStream, три круга. Каждый цикл сообщает свой лучший, медианный и худший круг.

Строка получает пометку «упирается в брокер», когда сырой клиент провёл прогон в ожидании сокета. Пробный замер засекает одну команду EXISTS и ответ на неё в каждой топологии, а круговая задержка публикуется вместе с машиной, так что арифметику можно проверить. Завершение записи потока или списка стоит отдельной команды, XACK или LREM, и через loopback этот обмен с сервером обходится дороже, чем доставка внутри этого крейта. Такие строки получают пометку. Pub/Sub ничего не завершает, и в этой строке видна работа над сокетом.

Подсчёт кода​

Каждый сценарий графика стоимости - сервис, который пишет пользователь, собранный без фичи testing. Сообщения добавляются из другого потока выполнения до того, как открывается измеряемая область, поэтому их создание в счёт не входит.

Инструкции даёт callgrind, выделения памяти - DHAT. Сценарий прогоняется на одной доставке, затем на 1000, затем на 2000. Разность двух последних - установившаяся стоимость сообщения, а одна доставка - холодный старт.

Сервер настоящий, поэтому счёт немного меняется между прогонами. За шесть прогонов итоговые инструкции сценария расходились не больше чем на 0,4 процента, а выделения памяти - на несколько блоков. Порог выделений каждого сценария - наибольшее увиденное число плюс запас в 0,1 процента. just bench-code не проходит, если выделений больше порога, который объявляет сценарий, а с --baseline=main - ещё и если инструкций стало больше чем на два процента.

Как запустить самому​

just bench

Рецепт поднимает стенд из docker-compose.test.yml, прогоняет все сценарии, останавливает стенд и перезаписывает docs/benchmarks/results.json. Это занимает около десяти минут, и машина на это время нужна целиком. Рецепт очищает RUSTFLAGS, поэтому бинарник не привязан к процессору, на котором его собрали. Профиль сборки записывается в документ вместе с числами.

just bench-code

Подсчёт кода поднимает тот же стенд, считает сценарии под valgrind против его одиночного сервера, останавливает стенд и перезаписывает раздел code того же документа. Ему нужен valgrind, а исполнитель бенчмарков рецепт устанавливает сам. just bench-code --save-baseline=main на main записывает базовый замер, а just bench-code --baseline=main на ветке сравнивает с ним.