2010-12-26 15 views
7

Tengo un montón de solicitudes de Django que ejecutan algunos cálculos matemáticos (escritos en C y ejecutados a través de un módulo Cython) que pueden tomar una cantidad indeterminada (del orden de 1 segundo) de tiempo para ejecutarse. Además, las solicitudes no necesitan acceder a la base de datos y son independientes entre sí y Django.Django Asynchronous Processing

En este momento todo es síncrono (utilizando tipos de trabajadores de Gunicorn con sync) pero me gustaría que sea asíncrono y sin bloqueos. En resumen me gustaría hacer algo:

  1. Recibir la petición AJAX
  2. Asignar tareas a un trabajador disponible (sin bloquear la aplicación principal de Django web)
  3. trabajador ejecuta la tarea en una cierta cantidad de tiempo desconocido
  4. Django devuelve el resultado del cálculo (una lista de cadenas) como JSON cada vez que se completa la tarea

soy muy nuevo en Django asíncrona, por lo que mi pregunta es ¿cuál es la mejor pila fo r haciendo esto

¿Es este tipo de proceso algo para lo que una cola de tareas es adecuada? ¿Alguien recomendaría Tornado + Celery + RabbitMQ, o tal vez alguna otra cosa?

¡Gracias de antemano!

+0

¿Qué hacer con los resultados de los cálculos? – sdolan

+0

Devuelve el resultado (como JSON) al navegador del usuario. –

Respuesta

14

El apio sería perfecto para esto.

Dado que lo que está haciendo es relativamente simple (léase: no necesita reglas complejas sobre cómo deben enrutarse las tareas), probablemente podría usar el servidor de Redis, lo que significa que no necesita configurar/configurar RabbitMQ (que, en mi experiencia, es más difícil).

utilizo Redis con los más dev una acumulación de apio, y aquí están los bits correspondientes de mi config:

 
# 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" 

También estoy usando django-celery, lo que hace que la integración con Django feliz.

Comente si necesita algún consejo más específico.

+1

Además, no he tenido ningún problema con el uso de parches 'gevent' + mono con Apio, por lo que si usas' gevent' gunicorn worker y monkeypatch 'apio', todo debería ser mágicamente asincrónico. –

+0

Gracias por la sugerencia. Intenté utilizar los trabajadores de 'gevent' + parches de mono en el pasado pero ralentiza mi aplicación a paso de tortuga. Sospecho que es debido a mi conexión de bloqueo con MySQL. ¿Tendría que moverme a una base de datos diferente? –

+0

Lo siento, no he trabajado con 'gevent' y otras bases de datos, así que no podría decirlo. Tal vez publicar otra pregunta preguntando sobre eso? –

0

Dado que planea hacer que sea asincrónico (probablemente usando algo como gevent), también podría considerar hacer un servicio web de backend roscado/bifurcado para el trabajo computacional.

El servidor de interfaz asíncrono podría manejar todo el trabajo ligero, obtener datos de bases de datos que son adecuadas para asincrónico (redis o mysql con un controlador especial), etc. Cuando se tiene que hacer un cálculo, el servidor frontend puede publicar todo ingrese los datos al servidor de back-end y recupere el resultado cuando el servidor de back-end termine de computarlo.

Dado que el servidor de interfaz es asincrónico, no bloqueará mientras espera los resultados. La ventaja de esto en comparación con el uso de apio, es que puede devolver el resultado al cliente tan pronto como esté disponible.

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