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

    На прошлой неделе был опубликован перевод статьи двухлетней давности Анализ производительности WSGI-серверов: Часть вторая, где незаслужено был обделен славой uWSGI.


    Необходимо срочно перепроверить тесты!



    Цели


    Я давно использую uWSGI, и хочу показать, что он не такой плохой, как описано в тестах 2016 года.
    Изначально, я просто хотел воспроизвести тесты, и разобраться, что не так с uWSGI.
    В коде отсутствуют версии используемых пакетов и модулей.


    Поэтому, запустить тесты и получить аналогичные результаты — не получиться.
    Далее мой квест, по запуску тестов и сравнение результатов на графиках.
    По просьбе читателей, добавлен NginX Unit.


    Шаги


    wrk 4.1.0


    Найти спеки, пропатчить, собрать
    Информация добавлена в readme.rd.


    docker stats


    За 2 года изменился вывод статистики.


    Была добавлена вторая колонка NAME, и это сломало парсер статистики.


    Что бы через два года не встретить подобную проблему, будем использовать форматированный вывод:


    - docker stats > "$BASE/$1.$2.stats" &
    + docker stats --format "{{.CPUPerc}} {{.MemUsage}}" > "$BASE/$1.$2.stats" &

    И соответственно, немного упростим код парсера.


    debian


    Сейчас latest образ debian соответствует версии 9.5, отобразим это в Dokerfile:


    - FROM debian
    + FROM debian:9.5

    В апреле 2016 latest соответствовал версии 8.4


    Тем не менеее, Аpache остался почти тем-же: сейчас версия Apache 2.4.25, а в 2016 это был Apache 2.4.10.


    cherrypy tornado uwsgi gunicorn bjoern meinheld mod_wsgi


    Даже нет смысла говорить о том, что модули изменились.
    Укажем текущие версии:


    - RUN pip install cherrypy tornado uwsgi gunicorn bjoern meinheld mod_wsgi
    + RUN pip install cherrypy==17.4.0 \
    +                 uwsgi==2.0.17.1 \
    +                 gunicorn==19.9.0 \
    +                 bjoern=2.2.3 \
    +                 meinheld==0.6.1 \
    +                 mod_wsgi==4.6.5

    Что там делает tornado, где запуск wsgi-файл для запуска tornado? Удаляем артефакт.
    Было бы не плохо вынести это в отдельный requirements.txt, но пока оставим так.


    cherrypy -> cheroot.wsgi


    Как было показно выше, актуальная версия 17.4.0.
    В апреле 2016 вероятно использовалась версия v5.1.0.
    А в 2017 году, в версии 9.0 произошли изменения, что отразилось на импорте сервера:


    - from cherrypy import wsgiserver
    - server = wsgiserver.CherryPyWSGIServer(
    + from cheroot.wsgi import Server as WSGIServer
    + server = WSGIServer(

    Socket errors: read 100500


    После описанных выше правок был запущен первый полноценный тест.
    Результаты были хороши: uwsgi выдавал не 3...200, а 7500...5000 запросов в секунду.
    Но при детальном рассмотрении полученных графиков, оказалось, что все ответы wrk детектил как ошибки чтения.


    После проверки десятка ключей запуска uwsgi, выяснилось, что ошибок нет при включении http1.1: --http-keepalive и --http11-socket.
    Причем, первый дает 7500...5000 запросов в секунду, а второй стабильные 29 тысяч!


    что же изменилось в uWSGI на данный момент


    Наиболее вероятно, что в августе 2016 использовалась версия uWSGI 2.0.12 (20151230).
    После, в мае, вышла uWSGI 2.0.13.


    Это было знаковое событие, но проблему производительности по версии wrk это не решало вплоть до 2018 года, выходом uWSGI 2.0.16:


    Back-ported HTTP/1.1 support (--http11-socket) from 2.1

    Вот почему uWSGI рекомендовали использовать с NginX,
    А почему это важно в рамках статьи, можно понять из этого тикета 2012 года.


    Почему тогда были такие результаты


    Я пробовал такие версии:


    • 2.0.12 для debian 8.4, на девятке она не собирается из-за свежей openssl.
    • 2.0.13...2.0.17 для debian 8.4 и 9.5

    Но таких плохих результатов, как 3...200 запросов в секунду, мне получить не удалось.
    Внимание привлекла строка запуска приложения:


    uwsgi --http :9808 --plugin python2 --wsgi-file app.py --processes ...

    Указание подключаемого плагина, говорит об установке uwsgi из репозитория, а не pip.
    Это может свидетельствовать об отсутствии у автора необходимого опыта работы с данным стеком.


    Поэтому, допускаю несколько возможностей:


    • тест каждого из uwsgi-серверов производился по отдельности, в разное время.
    • имел место какой-то конфликт системной версии uwsgi, и установленой через pip.
    • версия wrk автора в 2016, имела какие-то особенности для работы по http1.0
    • uwsgi запускался с другим набором параметров
    • заказная статья, цифры с потолка.

    Какие результаты сейчас


    uWSGI на графиках несколько:
    Первые два uWSGI и uWSGIbase (v2.0.17.1), выполнялись в долгом тесте, со своими конкурентами, с параметрами:
    --http11 :9808 --processes 5 --threads 2 --enable-threads.
    --http11 :9808 --processes 5.
    Как показала практика, качественной разницы НЕТ, для теста приложения пустышки.


    И, отдельно, версиии uWSGI 2016 года:
    uWSGI-v2.0.12th-old и uWSGI-v2.0.12nt-old — соответственно v2.0.12 с тредами и без в контейнере debian 8.4.
    --http :9808 --http-keepalive --processes 5 --threads 2 --enable-threads
    --http :9808 --http-keepalive --processes 5


    RPS 2018 ALL
    uWSGI занимает 2е место, не снижая результатов при увеличении нагрузки.
    На третьем месте — NginX Unit.


    RPS 2018 LOW
    В low-сегменте uWSGI-v2.0.12 лучше всех, даже при увеличении нагрузки.


    LATENCIES 2018 ALL
    Тут видим, как не с лучшей стороны показал себя Unit.


    LATENCIES 2018 LOW
    uWSGI и CherryPy несомненные победители по latency.



    Эта картинка аналогична 2016-му году.



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



    А новый uWSGI, gunicorn, mod_wsgi — уверенно "держат планку", и это о многом говорит.



    Cтарые uWSGI начинают резко набирать ошибки уже после 300 открытых соединений.



    Unit и CherryPy — без ошибок!
    Bjoern начинает сдавать с 1000 соединений.
    А вот с новым uWSGI странности, начиная 200 соединений, мы получаем 50 ошибок, и число больше не увеличивается. Этот момент требует детального рассмотрения.


    Все данные собраны тут
    Все изменения кода можно увидеть в RP.


    Выводы


    uWSGI не так уж плох, или даже очень хорош!
    Если вам не нравятся результаты тестов WRK, попробуйте возпользоваться другими инструментами.

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

    Каким wsgi-сервером вы пользуетесь?

    • 64.2%uWSGI36
    • 39.2%gunicorn22
    • 0%meinheld0
    • 0%bjorn0
    • 3.5%cherrypy2
    • 5.3%NGINX-unit3
    • 5.3%tornado3
    • 10.7%другой вариант, напишу в комментариях6
    • +18
    • 5,2k
    • 9
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 9

      0
      Спасибо, сам хотел проверить, но вы спасли моё время.
      Общий вывод для себя сделал такой: даже не смотря на то, что uWSGI иногда проигрывает на некоторых тестах, он делает это не на порядок, и выдаёт более стабильные характеристики в зависимости от нагрузки, а значит пока с него некуда переезжать.
        0
        Еще есть unit от nginx, нет желание добавить его в сравнение?

          0

          Может быть, но не обещаю. Цель "отбелить uWSGI" — достигнута.
          Так я хотел написать и поставить точку.


          Но вот тут оказалась интересная статья.
          Тестировали ApacheBench, но там те-же знакомые цифры… 7500 и 30 000.
          Поэтому — да, интересно, будет.

            0

            Готово.
            Результаты в целом совпадают с https://itnext.io/performance-comparison-between-nginx-unit-and-uwsgi-python3-4511fc172a4c
            Но там нет показателей памяти и отклика, а это согласитесь, тоже важно.

              0
              Спасибо.
            0
            Internet Information Services)
              0
              Пара вопросов:

              1. Почему ни в оригинальном бенчмарке, ни в свежем, не сконфигурирован thread_pool у CherryPy (по умолчанию 10 + только один процесс)?
              2. Аналогичный вопрос по meinheld серверу, его никто не запускает без gunicorn'а, см. официальную документацию.

              Выглядит очень странно, когда только gunicorn & uwsgi имеют относительно корректную конфигурацию в плане cpu/threads, а остальное предоставлено «из коробки», при условии, что практически все указанные сервера обычно запускаются под gunicorn. Как можно сравнивать uWSGI в конфигурации «PROCESSOR_COUNT * 2 + 1, да по 2 треда, пожалуйста»?

              Попробую поиграться и сделать PR. Было бы неплохо сравнить с Py3/PyPy (повлияет на некоторые сервера) и отдельно сравнить с ASGI (uvicorn тот же, или hypercorn)

              P.S. Тот же gunicorn default 1 thread per worker (не уверен, как повлияет, надо тестировать).
                +1
                Пара вопросов: — Почему… CherryPy… Аналогичный вопрос по meinheld ...

                ДА, в целом, я с вами согласен.
                Но, я в описал Свои Цели — это uWSGI. Были проделаны минимальные изменения кода автора, аналитика причин плохих результатов uWSGI 2016 и всежие результаты по методике автора.
                Кроме того, разныцы между uWSGI и uWSGIbase (без тредов) в этом тесте нет.
                Но, она будет, на реальном приложении…
                Поэтому не думаю, что что-то изменится при тюнинге CherryPy и meinheld.


                Попробую поиграться и сделать PR.

                Я обновил статью, добавлен NGINX Unit и PR автору оригинала.
                Можете отталкиваться от моего PR.
                Но заранее предупреждаю, запуск всех тестов — долгий процесс. Тестировал на ноуте без DE.

                  0
                  И у вас отлично получилось, спасибо за статью. Только век ASGI уже пришел, Andrew пилит Django в async стиле, есть Channels 2, есть куча ASGI серверов на вкус и цвет, да и событийные лупы разные бывают нынче. Видел попытку добавить поддержку ASGI в uWSGI, посмотрим, что выйдет. Спасибо еще раз!

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

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