Хабрахабр

Анализ производительности 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, либо версия, которую мы установили, имеет базовые ошибки.
Теги
Показать больше

Похожие статьи

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть