Анализ производительности WSGI-серверов: Часть вторая

    Данная статья является переводом статьи Кевина Голдберга «A Performance Analysis of Python WSGI Servers: Part 2» dzone.com/articles/a-performance-analysis-of-python-wsgi-servers-part с небольшими дополнениями от переводчика.

    image

    Введение


    В первой части этой серии Вы познакомились с WSGI и с шестью наиболее популярными по мнению автора WSGI-серверами. В этой части Вам будет показан результат анализа производительности этих серверов. С этой целью была создана специальная тестовая песочница.

    Конкурсанты


    Из-за нехватки времени исследование было ограничено шестью WSGI-серверами. Весь код с инструкциями по запуску для этого проекта размещен на GitHub. Возможно со временем проект будет расширяться и будут представлены анализы производительности для других WSGI-серверов. Но пока речь пойдёт о шести серверах:


    1. Bjoern описывает себя как « сверхбыстрый WSGI-сервер» и может похвастаться тем, что это «самый быстрый, самый маленький и легкий WSGI-сервер». Мы создали небольшое приложение, использующее большинство параметров библиотеки по умолчанию.
    2. CherryPy - чрезвычайно популярный и стабильный фреймворк и WSGI-сервер. Этот небольшой скрипт использовался для обслуживания нашего образца приложения через CherryPy.
    3. Gunicorn был вдохновлен сервером Unicorn от Ruby (отсюда и название). Он скромно утверждает, что он «просто реализован, легок в использовании и довольно быстрый». В отличие от Bjoern и CherryPy, Gunicorn является автономным сервером. Мы создали его с помощью этой команды. Параметр «WORKER_COUNT» был установлен в два раза больше доступных ядер процессора, плюс один. Это было сделано на основании рекомендаций из документации Gunicorn.
    4. Meinheld - это высокопроизводительный WSGI-совместимый веб-сервер, который утверждает, что он легкий. Основываясь на примере, указанном на сайте сервера, мы создали своё приложение.
    5. mod_wsgi создан тем же создателем, что и mod_python. Подобно mod_python, он доступен только для Apache. Однако он включает инструмент под названием «mod_wsgi express», который создаёт минимально возможный инстанс Apache. Мы сконфигурировали и использовали mod_wsgi express с помощью этой команды. Чтобы соответствовать Gunicorn, мы настроили mod_wsgi т.о, чтобы создать worker-ов вдвое больше чем ядер процессора.
    6. uWSGI - полнофункциональный сервер приложений. Как правило, uWSGI сопрягается с прокси-сервером (например: Nginx). Однако, чтобы лучше оценить производительность каждого сервера, мы попытались использовать только голые серверы и создали двух worker-ов для каждого доступного ядра процессора.

    Бенчмарк


    Чтобы сделать тест максимально объективным, был создан Docker-контейнер для изоляции тестируемого сервера от остальной части системы. Также использование Docker-контейнера гарантировало, что каждый запуск начинается с чистого листа.

    Сервер:


    • Изолирован в Docker-контейнере.
    • Выделено 2 ядра процессора.
    • Оперативная память контейнера была ограничена до 512 МБ.

    Тестирование:


    • wrk, современный инструмент HTTP-бенчмаркинга, запускал тесты.
    • Серверы были протестированы в произвольном порядке с увеличением числа одновременных соединений в диапазоне от 100 до 10000.
    • wrk был ограничен двумя ядрами ЦПУ, не используемыми Docker.
    • Каждый тест длился 30 секунд и повторялся 4 раза.

    Метрика:


    • Среднее количество постоянных запросов, ошибок и задержек предоставлялось wrk.
    • Встроенный в Docker, мониторинг показывал уровни использования ЦПУ и ОЗУ.
    • Самые высокие и самые низкие показания были отброшены, а остальные значения были усреднены.
    • Для любопытных мы отправили полный скрипт на GitHub.

    Результаты


    Все исходные показатели производительности были включены в репозиторий проекта, а также предоставлен сводный CSV-файл. Также для визуализации были созданы графики в среде Google-doc.

    Зависимость RPS от числа одновременных соединенинй


    На этом графике показано среднее количество одновременных запросов; Чем выше число, тем лучше.

    image

    image

    • Bjoern: Явный победитель.
    • CherryPy: Несмотря на то, что он написан на чистом Python, он был лучшим исполнителем.
    • Meinheld: Отличные показатели, учитывая скудные ресурсы контейнера.
    • mod_wsgi: Не самый быстрый, но производительность была последовательной и адекватной.
    • Gunicorn: Хорошая производительность при более низких нагрузках, но прослеживается борьба при большом количестве соединений.
    • uWSGI: Разочаровал плохими результатами.

    ПОБЕДИТЕЛЬ: Bjoern

    Bjoern


    По количеству постоянных запросов Bjoern является очевидным победителем. Однако, учитывая, что цифры намного выше, чем у конкурентов, мы немного скептически настроены. Мы не уверены в том, что Bjoern действительно настолько ошеломляюще быстрый. Сначала мы тестировали серверы по алфавиту, и мы думали, что Bjoern получил несправедливое преимущество. Однако даже после запуска серверов в произвольном порядке сервера и повторного тестирования результат остался прежним.

    uWSGI


    Мы были разочарованы слабыми результатами uWSGI. Мы ожидали, что он окажется в лидерах. Во время тестирования мы заметили, что логи uWSGI печатает на экране, и первоначально мы объяснили отсутствие производительности дополнительной работой, которую выполнял сервер. Тем не менее, даже после добавленной опции «--disable-logging», uWSGI по-прежнему является самым медленным сервером.

    Как упоминалось в руководстве uWSGI, оно обычно сопрягается с прокси-сервером, таким как Nginx. Однако мы не уверены, что это может объяснить такую ​​большую разницу.

    Задержка


    Задержка — это количество времени, прошедшего между запросом и его ответом. Более низкие цифры — лучше.

    image

    • CherryPy: Хорошо справлялся с нагрузкой.
    • Bjoern: В целом низкие задержки, но лучше работает при меньшем количестве одновременных соединений.
    • Gunicorn: хорош и последователен.
    • mod_wsgi: Средняя производительность, даже при большом количестве одновременных соединений.
    • Meinheld: В целом, приемлемая производительность.
    • uWSGI: uWSGI снова на последнем месте.

    ПОБЕДИТЕЛЬ: CherryPy

    Использование ОЗУ


    Эта метрика показывает требования к памяти и «легкость» каждого сервера. Более низкие цифры — лучше.

    image

    • Bjoern: Чрезвычайно легкий. Использует всего лишь 9 МБ ОЗУ для обработки 10 000 одновременных запросов.
    • Meinheld: Такой же как Bjoern.
    • Gunicorn: Умело справляется с высокими нагрузками с едва заметным потреблением памяти.
    • CherryPy: Первоначально нуждался в небольшом количестве оперативной памяти, но её использование стремительно увеличивалось с ростом нагрузки.
    • mod_wsgi: На более низких уровнях он был одним из наиболее интенсивных в памяти, но оставался довольно последовательным.
    • uWSGI: Очевидно, что у тестируемой нами версии проблемы с количеством потребляемой памяти.

    ПОБЕДИТЕЛИ: Bjoern и Meinheld

    Количество ошибок


    Ошибка возникает, когда сервер падает, прерывается или истекает время запроса. Чем ниже, тем лучше.

    image

    Для каждого сервера мы рассчитали отношение общее отношение количества запросов к числу ошибок:

    • CherryPy: коэффициент ошибок около 0, даже при высоком количестве соединений.
    • Bjoern: Ошибки встречались, но это компенсировалось количеством обработанных запросов.
    • mod_wsgi: Хорошо работает с приемлемой частотой ошибок 6%.
    • Gunicorn: Работает с 9-процентной частотой ошибок.
    • uWSGI: Учитывая низкое количество запросов, которые он обслуживал, он оказался с 34-процентной частотой ошибок.
    • Meinheld: Упал на более высоких нагрузках, выбросив более 10 000 ошибок во время самого требовательного теста.

    ПОБЕДИТЕЛЬ: CherryPy

    Использование ЦПУ


    Высокое использование ЦПУ не является хорошим или плохим, если сервер работает хорошо. Однако, это даёт некоторые интересные сведения о работе сервера. Поскольку использовались два ядра ЦПУ, максимальное возможное использование составляет 200 процентов.

    image

    • Bjoern: однопоточный сервер, о чем свидетельствует его последовательное использование на 100% ЦПУ.
    • CherryPy: многопоточный, но застрял на 150-ти процентах. Это может быть связано с GIL Python.
    • Gunicorn: использует несколько процессов с полным использованием ресурсов ЦПУ на более низких уровнях.
    • Meinheld: однопоточный сервер, использующий ресурсы ЦПУ как Bjoern.
    • mod_wsgi: Многопоточный сервер использующий все ядра ЦПУ на протяжении всех измерений
    • uWSGI: очень низкое использование ЦПУ. Потребление ресурсов ЦПУ не превышает 50-ти процентов. Это одно из доказательств того, что uWSGI неправильно сконфигурирован.

    ПОБЕДИТЕЛЬ: Нет, поскольку это скорее наблюдение в поведении, чем сравнение в производительности.

    Заключение


    Подведем итог! Вот некоторые общие идеи, которые можно почерпнуть из результатов каждого сервера:

    • Bjoern: Оправдывает себя как «супербыстрый, ультралегкий WSGI-сервер».
    • CherryPy: Высокая производительность, маленькое потребление памяти и маленькое количество ошибок. Неплохо для чистого Python.
    • Gunicorn: Хороший сервер для средних нагрузок.
    • Meinheld: Хорошо работает и требует минимальных ресурсов. Тем не менее, борется с более высокими нагрузками.
    • mod_wsgi: Интегрируется в Apache и отлично работает.
    • uWSGI: Очень разочаровал. Либо мы неправильно сконфигурировали uWSGI, либо версия, которую мы установили, имеет базовые ошибки.
    • +11
    • 4,4k
    • 4
    Поделиться публикацией

    Похожие публикации

    Комментарии 4
      0
      Не делайте одновременно синие и голубые линии, пожалуйста. Очень трудно различить цвета, например, в тесте про потребление ОЗУ.

      upd: это перевод, прошу прощения.
        0
        Я так понимаю, что у uWSGI основной метод работы это его собственный протокол который нативно поддерживается Nginx через директиву uwsgi_proxy. А с HTTP он может работать и не очень. Что впрочем существенный недостаток. Но интересно было бы посмотреть как такой же тест работает через прокси.
          0
          Более того, без nginx вообще неверно мерить, ибо nginx берёт на себя проблему медленных клиентов и статики, что WSGI серверы делать не обязаны.
          0

          Минус Bjoern в том, что он не кросс-платформенный. Например, мне не удалось заставить его работать под Windows (Cygwin).

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое