RQ - alternatywa dla Celery Task Queue?
Celery
Celery
był obiecującym pakietem umożliwiającym kolejkowanie i asynchroniczne wykonywanie zadań, oraz w pewnym stopniu rozproszenie systemu. Kiedyś udało mi się nawet pracować z w miarę stabilną wersją, lecz wskutek błędu związanego z task.retry
zostałem zmuszony poszukać rozwiązania w upgrade pakietu. Obecnie major release Celery
nosi numer 3 i niestety niewiele się zmieniło w kwestii stabilności.
Autor pakietu, Ask Solem, ma łeb na karku ale wziął sobie na niego za dużo projektów. Mam wrażenie, że facet już nad tym nie panuje. Celery opiera się na jego dwóch innych produktach: Kombu
i Billiard
. Kombu zastępuje kilka starszych pakietów (również jego autorstwa). Billiard zastępuje standardowy multiprocessing
(autor chciałby, aby kiedyś znalazł się w dystrybucji Pythona). Niestety Billiard
również jest delikatnie zmaszczony
.
Za tymi pakietami głównie włóczy się smród Django , choć Ask Solem stara się od dawna pozbyć tejże zależności. Włóczy się też atmosfera niestabilności mimo zaklęć w setup.py .
Główne wady Celery:
- brak stabilności mimo intensywnego rozwoju, nieoczekiwane zachowanie podczas pracy
- przeładowanie features, z których podstawowe nadal nie działają stabilnie
- morderstwo standardowego loggera
- zbyt dużo punktów podatnych na błędy i awarie (celery -> kombu -> billiard -> amqplib -> erlang -> rabbitmq)
- zależności z django na każdym kroku
- trudność w debugowaniu
- brak możlwości samodzielnej poprawy przez zbyt skomplikowaną budowę pakietu.
RQ
RQ jest prostą implementacją kolejkowania zadań dla Pythona. Autor Vincent Driessen postawił na prostotę i czas wdrożenia. Przede wszystkim nie ma zależności od Django , choć istnieje pakiet ułatwiający taką integrację. Widać tu wyraźnie, jak wyglądał proces tworzenia pakietu. Nie ma mowy o zaszłościach i nieuzasadnionych zależnościach.
Zasada działania RQ jest prostsza od Celery, a punktów podatnych na wywalenie jest o wiele mniej - właściwie sam RQ albo Redis . Uruchomienie workerów pod kontrolą supervisord jest dziecinnie proste. Wielki plus dla łatwej integracji z Sentry.
Funkcje uruchamiane przez workery nie muszą być opakowywane żadnymi dekoratorami. Są zwykłymi funkcjami, którym worker przekaże argumenty. Jedyny warunek to konieczność umieszczenia funkcji w module (nie da się zdefiniować funkcji w __main__
, albo użyć jakiegoś builtina), ale to ma marginalne znaczenie. Na koniec warto zauważyć, że pakiet nie ma idiotycznej nazwy - spróbujcie poszukać w Google czegoś o Celery
.
Wady i zalety
Wady:
- Python only
- instancja Redis per projekt
- rozpraszanie workerów za pomocą dostawiania instancji Redisa
- brak wbudowanego mechanizmu
task.retry
- wolniejsze uruchamianie zadań (process fork)
Zalety:
- szybkość i prostota wdrożenia
- podobne high-level API do Celery , które pozwala na łatwą migrację
- mało potencjalnych miejsc awarii
- odporność na wycieki pamięci tasków