2010-12-26 18 views
7

Mam kilka żądań Django, które wykonują obliczenia matematyczne (zapisane w C i wykonywane przez moduł Cython), które mogą zająć nieokreśloną ilość (rzędu 1 sekundy) czasu do wykonania. Również żądania nie muszą mieć dostępu do bazy danych i są niezależne od siebie nawzajem i od Django.Procesor asynchroniczny Django

Teraz wszystko jest synchroniczne (używając Gunicorn z typami pracującymi sync), ale chciałbym, aby było to asynchroniczne i nieblokujące. W skrócie chciałbym zrobić coś:

  1. Otrzymuj żądania AJAX
  2. przydzielać zadania do dostępnego pracownika (bez blokowania głównego aplikacji internetowej Django)
  3. Pracownik wykonuje zadania w jakiejś nieznanej ilości czasu
  4. Django zwraca wynik obliczeń (listę ciągów) jako JSON, gdy zadanie kończy

Jestem bardzo nowym asynchronicznym Django, a więc moje pytanie brzmi, co jest najlepszym stos fo r robi to.

Czy jest to proces, do którego dobrze nadaje się kolejka zadań? Czy ktoś poleciłby Tornado + Celery + RabbitMQ, czy może coś innego?

Z góry dziękuję!

+0

Co robisz z wynikami obliczeń? – sdolan

+0

Powróć wynik (jako JSON) do przeglądarki użytkownika. –

Odpowiedz

14

Seler byłby do tego idealny.

Ponieważ to, co robisz, jest stosunkowo proste (przeczytaj: nie potrzebujesz skomplikowanych reguł dotyczących routingu zadań), prawdopodobnie będziesz mógł uciec z użyciem zaplecza Redis, co oznacza, że ​​nie musisz setup/configure RabbitMQ (co, z mojego doświadczenia, jest trudniejsze).

używam Redis z najbardziej kompilacji dev selera, a tu są odpowiednie bity mojego 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" 

Używam również django-celery, co sprawia, że ​​integracja z Django szczęśliwym.

Komentarz, jeśli potrzebujesz bardziej szczegółowej porady.

+1

Nie miałem też problemu z używaniem łatki "gevent' +" z Selerami, więc jeśli użyjesz 'gevent' gunicorn worker i monkeypatch' selera ', wszystko powinno być magicznie asynchroniczne. –

+0

Dzięki za cynk. Próbowałem już używać 'gevent' workers + patching małpek, ale spowalnia to moją aplikację do indeksowania. Podejrzewam, że jest to spowodowane moim blokującym połączeniem z MySQL. Czy muszę przejść do innej bazy danych? –

+0

Niestety, nie pracowałem z 'gevent' i innymi bazami danych, więc nie mogłem powiedzieć. Może zadaj kolejne pytanie o to pytanie? –

0

Ponieważ planujesz uczynić to asynchronicznym (prawdopodobnie przy użyciu czegoś podobnego do gevent), możesz również rozważyć utworzenie sieciowej obsługi wątków/wideł dla prac obliczeniowych.

Asynchroniczny serwer frontendu może obsłużyć wszystkie prace light, pobrać dane z baz danych, które są odpowiednie dla async (redis lub mysql ze specjalnym sterownikiem), itp. Kiedy obliczenia muszą być wykonane, serwer frontend może publikować wszystkie Wprowadź dane do serwera zaplecza i pobierz wynik, gdy serwer zaplecza zakończy obliczenia.

Ponieważ serwer frontendu jest asynchroniczny, nie będzie blokować podczas oczekiwania na wyniki. Zaletą tego, w przeciwieństwie do używania selera, jest to, że możesz zwrócić wynik klientowi, gdy tylko stanie się on dostępny.

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