@bubaley

Как правильно оптимизировать нагрузку на Django?

Здравствуйте

Есть проект на Django с 5000+ пользователей
В рамках этого проекта выполняется большой алгоритм (около 7 вложенных циклов)
Сам считается на каждые 30 секунд текущего дня, в итоге вход в самые низкую функцию происходит больше 200 000 раз. В среднем выполнение расчета занимает ~3 секунды, при большем объеме может доходить на 5-10 секунд.
Проблема в том, что при выполнении этой операции, сам сервер начинает висеть и ждать пока другой пользователь получит результат расчета.
Хочется максимально оптимизировать prod версию.

Django работает в одном экземпляре в docker-е. Работает с помощью daphne. В проекте используется много websocket событий (сказали, что только в нем все с вебсокетом работает как часы)
Запускаю контейнер с помощью команды. Nginx проксирует все запросы в него.
command: sh -c "python manage.py migrate && daphne -b 0.0.0.0 --proxy-headers core.asgi:application"

Сам сервер 8 ядер, 16 оперативки и ssd на 200

Может стоит изменить публикацию или есть какие-то подводные камни о которых я не знаю. Буду рад выслушать все советы!
  • Вопрос задан
  • 261 просмотр
Пригласить эксперта
Ответы на вопрос 3
Выполняйте тяжелые операции асинхронно, в отдельном процессе, особенно если это cpu-bound задачи. Не пользователь Django, но предположу, что Django Q здесь вам поможет.
Ответ написан
Комментировать
@deliro
Первое. daphne — на помойку. Я в своё время наплевался с неё и переехал на gunicorn + uvicorn. Потому что daphne вообще не настраивается. Вот сколько у вас процессов-воркеров, по-вашему? А сколько потоков? А сколько ивент-лупов? А зачем ему сертификаты? Стало быть, это сервер, который может торчать наружу? Но ведь это не так.

Второе — в зависимости от типа задачи, которая выполняется "3-10 секунд", нужно или забить на это, или выносить в очередь. Если это IO, то асинхронная функция может длиться хоть вечность, она не будет влиять на соседние запросы (на самом деле конечно будет, но крайне незначительно). Если это CPU — только очереди задач. Celery например. Но с ним тоже много проблем, поэтому мы последнее время пишем самописные django-management команды, которые слушают очередь.

Третье. Джанга в целом не очень хорошо подходит для асинхронщины по дизайну (и вебсокетов соответсвенно тоже). Да, есть неуклюжие попытки в виде channels и даже django 3 по подружению её с миром асинка, но это всегда большие компромиссы с большим количеством "но". Поэтому, если есть возможность (например, проект стартовал "вчера"), то переезжай на что-то более способное в настоящую асинхронность (fastapi например)
Ответ написан
@vitaly_il1
DevOps Consulting
1)
Сам считается на каждые 30 секунд текущего дня, в итоге вход в самые низкую функцию происходит больше 200 000 раз. В среднем выполнение расчета занимает ~3 секунды, при большем объеме может доходить на 5-10 секунд.

Чтобы ответить на запрос каждого пользователя?

2) сколько запросов в минуту? Есть какое-то кол-во запросов при котором производительность удовлетворительна?

3) Я бы посмотрел на нагрузку на каждом CPU, на диск и базу данных (если есть).
Возможно стоит запустить несколько инстансов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы