2010-12-26 14 views
7

Ho un sacco di richieste Django che eseguono alcuni calcoli matematici (scritti in C ed eseguiti tramite un modulo Cython) che possono richiedere un ammontare indeterminato (dell'ordine di 1 secondo) di tempo per l'esecuzione. Inoltre le richieste non hanno bisogno di accedere al database e sono tutte indipendenti l'una dall'altra e Django.Elaborazione asincrona di Django

In questo momento tutto è sincrono (utilizzando Gunicorn con i tipi di lavoro sync) ma vorrei rendere questo asincrono e non bloccante. Insomma mi piacerebbe fare qualcosa:

  1. mandare la richiesta AJAX
  2. Assegnare compito di un lavoratore a disposizione (senza bloccare l'applicazione principale web Django)
  3. Worker esegue compito in una certa quantità di tempo indeterminato
  4. Django restituisce il risultato del calcolo (una lista di stringhe) come JSON ogni volta che l'attività viene completata

sono molto nuovo per asincrono Django, e quindi la mia domanda è che cosa è la migliore pila fo sto facendo questo

Questo tipo di processo è adatto a una coda di attività? Qualcuno lo consiglierebbe Tornado + Celery + RabbitMQ, o forse qualcos'altro?

Grazie in anticipo!

+0

Cosa si fa con i risultati dei calcoli? – sdolan

+0

Restituisce il risultato (come JSON) al browser dell'utente. –

risposta

14

Il sedano sarebbe perfetto per questo.

Dato che quello che stai facendo è relativamente semplice (leggi: non hai bisogno di regole complesse su come devono essere instradati i compiti), potresti probabilmente cavartela usando il backend Redis, il che significa che non hai bisogno di configura/configura RabbitMQ (che, secondo la mia esperienza, è più difficile).

Io uso Redis con il più una build dev di sedano, e qui ci sono i bit rilevanti della mia configurazione:

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

Sto anche utilizzando django-celery, il che rende l'integrazione con Django felice.

Commento se è necessario un consiglio più specifico.

+1

Inoltre, non ho avuto alcun problema con l'uso di 'gevent' + monkey patching con Celery, quindi se si usa il' gevent' gunicorn worker e monkeypatch 'celery', tutto dovrebbe essere magicamente asincrono. –

+0

Grazie per il suggerimento. Ho provato a usare gevent' workers + monkey patching in passato ma rallenta la mia applicazione. Sospetto che sia dovuto alla mia connessione di blocco con MySQL. Dovrei passare a un altro database? –

+0

Siamo spiacenti, non ho lavorato con 'gevent' e altri database, quindi non ho potuto dire. Magari postare un'altra domanda per chiederglielo? –

0

Dato che si sta pianificando di renderlo asincrono (presumibilmente usando qualcosa come gevent), si potrebbe anche prendere in considerazione la possibilità di creare un servizio Web di backend threaded/forked per il lavoro computazionale.

Il server di frontend async può gestire tutto il lavoro leggero, ottenere dati da database che sono adatti per asincrona (redis o mysql con un driver speciale), ecc. Quando un computo deve essere fatto, il server di frontend può postare tutti immettere i dati nel server di back-end e recuperare il risultato quando il server back-end esegue il calcolo.

Poiché il server di frontend è asincrono, non si bloccherà durante l'attesa dei risultati. Il vantaggio di questo rispetto all'uso del sedano è che è possibile restituire il risultato al client non appena disponibile.

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