2010-12-26 3 views
7

У меня есть куча запросов Django, выполняющая некоторые математические вычисления (написанные на C и выполняемые через модуль Cython), которые могут принимать неопределенное количество (порядка 1 секунды) времени для выполнения. Кроме того, запросы не нуждаются в доступе к базе данных и не зависят друг от друга и Django.Django Asynchronous Processing

Сейчас все синхронно (с использованием Gunicorn с рабочими типами sync), но я хотел бы сделать это асинхронным и неблокирующим. Короче говоря, я хотел бы сделать что-то:

  1. Получить запрос AJAX
  2. Выделяют задачу к свободному работнику (без блокировки основного веб-приложение Django)
  3. работник выполняет задание в какой-то неизвестное количество времени
  4. Джанго возвращает результат вычисления (список строк) в формате JSON, когда задача завершает

Я новичок в асинхронном Django, и поэтому мой вопрос, что это лучший стек Ф.О. r делать это.

Это какой-то процесс, для которого хорошо подходит задача? Кто-нибудь порекомендует Tornado + Celery + RabbitMQ или, возможно, что-то еще?

Заранее благодарен!

+0

Что вы будете делать с результатами вычислений? – sdolan

+0

Вернуть результат (как JSON) в браузер пользователя. –

ответ

14

Сельдерей идеально подходит для этого.

Поскольку вы делаете это относительно просто (читайте: вам не нужны сложные правила о том, как следует перенаправлять задачи), возможно, вам удастся использовать бэкэнд Redis, а это значит, что вам не нужно setup/configure RabbitMQ (что, по моему опыту, сложнее).

Я использую Redis с большинством в Dev сборки сельдерея, а вот соответствующие биты моей конфигурации:

 
# Use redis as a queue 
BROKER_BACKEND = "kombu.transport.pyredis.Transport" 
BROKER_HOST = "localhost" 
BROKER_PORT = 6379 
BROKER_VHOST = "0" 

# Store results in redis 
CELERY_RESULT_BACKEND = "redis" 
REDIS_HOST = "localhost" 
REDIS_PORT = 6379 
REDIS_DB = "0" 

Я также использую django-celery, что делает интеграцию с Джанго счастливым.

Комментарий, если вам нужен более конкретный совет.

+1

Кроме того, у меня не было проблем с использованием патчей 'gevent' + monkey с Celery, поэтому, если вы используете« gevent »gunicorn worker и monkeypatch« сельдерей », все должно быть просто волшебным асинхронным. –

+0

Спасибо за подсказку. Я пробовал использовать «gevent» worker + monkey patching в прошлом, но он замедляет мое приложение до обхода. Я подозреваю, что это связано с моей блокирующей связью с MySQL. Мне нужно переместиться в другую базу данных? –

+0

Извините, я не работал с 'gevent' и другими БД, поэтому не мог сказать. Может быть, еще один вопрос, спрашивающий об этом? –

0

Поскольку вы планируете сделать его асинхронным (предположительно, используя что-то вроде gevent), вы также можете рассмотреть возможность создания многопоточного/forked бэкэнд-сервиса для вычислительной работы.

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

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

client browser <> async frontend server <> backend server for computations