Как стать автором
Обновить

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

Господи, это же треш, а не сравнение. Почему кстати автор не сравнивает один к одному? Что за магические значения 5 и 16?


Оптимальное количество воркеров у асинхронных и синхронных фреймворков различается. У этого есть очевидные причины.

Эм… нет

Почему в разных конфигурациях используется разное количество воркеров?

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

Эта его методика никуда не годится. Человек сравнил теплое с мягким на основе каких-то субъективных метрик.

Почему? Человек нашёл максимум производительности в зависимости от количества воркеров. Что не так?

Максимум производительности чего?


Эта методика — чистый подгон под результат. Да, для этого конкретного бессмысленного синтетического теста были найдены оптимальные значения количества воркеров. Если бы эти значения были универсальными — они были бы — сюрприз! — дефолтными и захардкоженными.


Это все равно, что решать задачу нахождения числа Фибоначчи — доставанием значения из предварительно подготовленного словаря. O(1), прикиньте.


Кроме того, выполнение атомарных быстрых запросов (испорченных обращением в базу, правда, которая тоже не резиновая, но ладно, простим; на общем фоне это выглядит просто как досадная оплошность) — нивелирует всю ценность асинхронности, потому что в таком сценарии сами воркеры параллелятся.


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

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

Неверно.


Максимум производительности данного конкретного приложения, имеющего столько же общего с любым реальным приложением, сколько сосновая палка с автоматом Калашникова.


Я даже подробно расписал это в своем предыдущем комментарии, хотя и тогда, и сейчас, мне это представляется очевидным.

Шок! Лишние операции замедляют программы! :-D

А если без шуток, то:

— Асинхронщина не только для быстродействия нужна.
— Не увидел в статье информации про количество соединений от воркера к pgbouncer, что сразу ставит под вопрос объективность тестирования.
  • Профиль нагрузки на сервер.

Нет, серьёзно, когда приложение лезет в БД, результаты бенчмарков сильно меняются

Для такого нужно отдельно тестировать ОРМ/Коннектор чтобы получить максимально чистые результаты. Это микрофреймворки, тем более, в них можно что угодно использовать.

В тестах асинхронных фрйемворков используется aiopg

да. не внимательно глянул

Ну как бы предсказуемо. Особенно предсказуемо если ты понимаешь что asyncio — это кооперативный event loop.
Ну и как бы в каждой нормальной статье или туториале по asyncio в самом начале пишут, для чего он был придуман.


Предлагаю автору повторить замеры но с измененным профилем нагрузки — не менее 10к долгоживущих HTTP/WebSocket соединений на воркера. Ну или в современных условиях можно и по 100к на воркера. И тогда посмотрим кто кого =)


Из анналов Stack Overflow:


if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
То ли в девзене то ли в радиоте уже оригинал статьи разнесли в пух и прах.

В радиоте было

А можно ссылку, пожалуйста?
А можно ссылку, пожалуйста?
блин, класс) Зато он блин асинхронный, робяты, вы ж не думали, что все будет бесплатно?

Хотелось бы увидеть код бенчмарков.

Всё в посте есть:


Вот репозиторий с полным исходным кодом проекта.

Спасибо, не увидел сразу!

Почему в тестах используется aiopg, а не asyncpg? Количество воркеров тоже крайне спорное.

Статья попахивает провокацией. Не объяснена объективность количества воркеров, а так же принцип выбора библиотек для Postgres. И к чему тут вообще Postgres если вроде как измеряем производительность web-фреймворков? Почему бы не замерить скорость ответа для статичной html страницы? Или замерить производительность для файлов > 10мб? Вопросов больше чем ответов

НЛО прилетело и опубликовало эту надпись здесь

Так он не захардкоживал. Он нашёл оптимальные значения, просто результаты для неоптимальных выкинул.

Пожалуй, объясню почему я написал про один к одному :) Я читал статью за неделю до того как она на хабре появилась и мне казалось, что вполне очевидно, что с ней не так.


Про "один к одному" за который в меня только ленивый здесь пальцем не ткнул. Заголовок поста "Асинхронный Python-код медленнее обычного кода" — и тут в общем-то сложно спорить. Можно написать что-то одинаковое и без какого-либо сетевого взаимодействия сравнить лоб в лоб. И мы выясним что и вправду три мешка картошки тяжелее чем один. Тут даже питон не надо знать чтоб понимать, что тест отработает так как написано в заголовке.


Но когда в тесте появляются запросы к БД и сам тест это HTTP-сервис, то в общем-то производительность всего теста становится зависимой не только от кода. Да и в общем-то, накинуть тяжелых запросов, и каких-нибудь постоянных соединений и все будет совсем не так однозначно.


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

НЛО прилетело и опубликовало эту надпись здесь

В статье про измерение производительности нет ни слова про измерение производительности. Идешь в предоставленный код — видишь там ab. Окей, действительно, никто тут производительность и не измерял.

Вот, например, результаты бенчмарка, созданного в рамках проекта Vibora (я этот фреймворк не тестировал, так как он относится к числу наименее популярных решений).

я бы сказал к числу мертвых. ведь в репозитории последний коммит был 17 месяцев назад(и то, редактировался readme. код же не обновлялся два года).
А где gunicorn + aiohttp?
Здесь явный пример соревнования гоночной феррари формулы один с трактором по бездорожью. И да. В таких условиях действительно, трактор быстрее.
Чтобы асинхронный код был производительнее синхронного, необходимо под это настроить с-но инрфраструктуру. В данном конкретном случае, по сути, измеряется производительность базы данных.
Реплицируйте базу данных на 10 серверов. Используйте кеш. Думаю результаты будут значительно отличаться от текущих.

Про репликацию базы согласен, а вот как кэш поможет в случае именно асинка — я не понял.


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


В этом плане этот тест как раз заставляет задуматься о реальном профиле нагрузке и необходимости настройки текущей инфраструктуры, вместо того чтобы бросаться переписывать все на asyncio в надежде получить профит из ничего

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

Тут и спорить не о чем. Каждый инструмент нужен для определенных вещей. Естественно нет смысла переписывать и даже писать с нуля сайтик, генерирующий 3 страницы в минуту с использованием ассинхронщины.

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


Речь не о сайте с 3rpm. А о том, что даже "высокая" нагрузка бывает разной и типичный crud асинк не ускорит (сам по себе)

> В данном конкретном случае, по сути, измеряется производительность базы данных

Почему тогда одна и та же БД с синхронным фронтендом работает быстрее?
Psycopg can issue asynchronous queries to a PostgreSQL database. An asynchronous communication style is established passing the parameter async=1 to the connect() function: the returned connection will work in asynchronous mode.

Это цитата из документации psycopg2
Судя по тому, что я вижу в коде, этот драйвер вообще работает в синхронном режиме. Причем это не изменяется и для ассинхронщины. С-но цикл событий блокируется при запросе к бд. И все преимущество сводиться на нет.
pool = psycopg2.pool.SimpleConnectionPool(
      1, 4, database="test", user="test", password="test", port=6432,
)

А должно быть для ассинхронного кода
pool = psycopg2.pool.SimpleConnectionPool(
      1, 4, database="test", user="test", password="test", port=6432, async=1
)
Не внимательно посмотрел. Все таки там используется aiopg.

Предлагаю автору запустить рядом с каждым бенчмарком slowhttptest, чтобы понять, почему запускать неасинхронный код в 2020 очень глупо. Спойлер: rps упадет примерно до нуля. И это будет более реально отражать жизнь, т.к. настоящие клиенты где-то на другой стороне довольно медленной сети.

Настоящие клиенты обращаются к nginx, который берёт на себя всю «медленную» работу вместе с буферизацией всего подряд, а к питон-серверу приходит быстрый запрос от 127.0.0.1 или вообще по UNIX-сокету

Слишком много "но" и ограничений, при которых эта схема работает. Например, сразу можно забыть о больших post-запросах, websocket, и многом другом, что не умещается в один буфер. И это если мы вообще говорим о HTTP, вне которого все еще хуже. Можно бесконечно затыкать все эти дыры костялями и различными параметрами в nginx там, где это возможно, а можно просто писать нормальный асинхронный код и не париться.


Дополнительно, если так получается, что неасинхронный код нужно обязательно выкладывать в продакшон под защитой nginx, то и бенчмарки нужно делать с nginx. Тогда как для асинхронных приложений его можно опустить (и использовать более простые и более производительные штуки).

Во-первых, все перечисленные проблемы в nginx решаются (и это вообще не проблемы), а во-вторых, плюшек от nginx НАМНОГО больше чем проблем. Я это когда-то расписывал на ruSO.

все перечисленные проблемы в nginx решаются

Лучшее решение любой проблемы — в первую очередь не создавать её себе на ровном месте


плюшек от nginx НАМНОГО больше чем проблем

Прочитал все по диагонали, все перечисленное например решается через traefik, который значительно быстрее.

Ну то есть в итоге вы всё равно предлагаете ставить какой-то дополнительный сервер перед питоном? Тогда на этом можно закончить, потому что я предлагаю ровно то же самое.

Предлагаю иметь опции. Все это мне напоминает phpшников, которые 10 лет назад кричали, что apache лучше, чем nginx, потому что, видите ли, у них бенчмарки их php-кода показывают, что с apache быстрее.

Я не утверждаю, что должен стоять конкретно nginx (это просто самое популярное решение), но должно стоять хотя бы что-нибудь — хоть тот же traefik (не сильно-то он и slower). Без дополнительного реверс-прокси поднять что-то похожее на реальный продакшен-сервер получится примерно никогда — основной мой посыл вот в этом вот. (Наверное, допишу упоминание traefik в посте на ruSO)

НЛО прилетело и опубликовало эту надпись здесь

К счастью, не могу сказать, потому что уже много лет не видел php нигде. Apache тем более. Но не думаю, что что-то изменилось, nginx сильно лучше.

traefik, который значительно быстрее.

И по вашей же ссылке английским по белому написано:


Traefik is obviously slower than Nginx

Внезапно. Ну тогда да, в этом моменте я неправ.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий