Применение slab-аллокаторов в высоконагруженных сетевых приложениях

RU / День 1 / 17:00 / Зал 2

Николай работает в компании, которая занимается защитой бизнеса от различных угроз в сети Интернет. Речь идет о парсинге, DDoS-атаках, скликивании и многом другом. Подобные решения представляют собой высоконагруженные сетевые приложения, которые способны пропускать через себя большие объемы трафика в единицу времени. Несмотря на все минусы, которые свойственны C++ в предприятии, возможно, современный C++ — это наиболее подходящий язык программирования для данных задач. Не только из-за того, что он может обеспечить желаемую производительность и сам по себе является мощным инструментом, но и потому, что вкупе с новыми стандартами и такими библиотеками как boost, порог вхождения в него не так и высок, как может казаться на первый взгляд.

Большинство сетевых приложений для работы с http-трафиком имеют классическую архитектуру. В них вы можете встретить сервер, клиент, сессии, пулы, парсеры и сериализаторы. Это стандартный набор классов, который на сегодняшний день очень удобно разрабатывать на boost.asio и boost.beast. Но, если мы говорим о серьезном объеме трафика, то примеры, которые каждый из нас копирует из документации boost.asio и развивает далее под свои задачи, могут оказаться далеко не настолько хороши, как кажется на первый взгляд. В серьезном продукте они требуют тщательной доработки.

Внутри команды Николая проделан большой путь по разработке похожего кода. Поддержали многие фичи из rfc для http 1.1. Реализовали свои строки и стрим-буферы, совместимые с boost.asio.streambuf, которые позволили минимизировать копирования памяти между сервер- и клиент- сессиями в момент проксирования трафика. Как итог, на выходе было получено хорошо работающее в продакшене сетевое приложение, способное выдерживать большие нагрузки и с лихвой решать поставленную перед бизнесом задачу.

Но ничто не совершенно. Одна из проблем, с которой Николай и его команда столкнулись на поздней стадии, — это фрагментация памяти, вызываемая постоянным созданием сервер-сессий для обработки входящих соединений. Проблема, которую не удалось решить с помощью tcmalloc и jemalloc, получилось победить за счет slab-аллокаторов (собственной C++ обертки поверх библиотеки libsmall из состава tarantool), которые сократили время пребывания приложения в функции malloc и операторе new более чем в два раза, и избавили нас от фрагментации памяти. Такое решение наложило определенные ограничения на архитектуру приложения, добавив свои сложности в написании асинхронного и многопоточного кода на boost.asio, но дало на выходе ожидаемый результат.

О том, как Николай и его команда преодолевали возникшие трудности и пойдет речь в этом докладе. Спикер также упомянет об архитектуре приложения, которое потребовало таких непростых оптимизаций, а далее перейдет непосредственно к использованию slab-аллокаторов в паре с boost.asio. Николай рассчитывает, что данная тема может быть полезна для разработчиков любых высоконагруженных сетевых приложений.

Комментарий программного комитета:

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