2014-05-13 10 views
9

Ho due tipi di compiti. L'attività A è generata da celerybeat ogni ora. Funziona immediatamente e genera migliaia (o molte migliaia) istanze di Attività B, ognuna delle quali ha un ETA di un giorno in futuro.In Celery, come posso impedire a task a lungo ritardo di bloccare quelli più recenti?

All'avvio, un'istanza del task A esegue e genera migliaia di Bs. E da quel momento in poi, non succede nulla. Dovrei vedere un altro A correre ogni ora, con altre migliaia di Bs. Ma in effetti non vedo nulla.

Al congelamento, rabbitmqctl mostra 1000 messaggi, con 968 pronto e 32 non riconosciuta. Un'ora dopo ci sono 1001 messaggi, 969 pronti e 32 non riconosciuti. E così via, ogni ora un nuovo messaggio è classificato come pronto. Presumibilmente, ciò che sta accadendo è che l'operatore sta prefetch su 32 messaggi ma non può agire su di essi, perché il loro ETA è ancora in futuro. Nel frattempo, le attività più recenti che dovrebbero essere eseguite in questo momento non possono essere eseguite.

Qual è il modo giusto per gestire questo? Sto indovinando che ho bisogno di più lavoratori, e forse più code (ma non sono sicuro di quest'ultimo punto). c'è un modo più facile? Ho provato a giocherellare con CELERYD_PREFETCH_MULTIPLIER e -Ofail (come discusso qui: http://celery.readthedocs.org/en/latest/userguide/optimizing.html) ma non riesco a farlo andare. La mia domanda è la stessa di questa: [[Django Celery]] Celery blocked doing IO tasks?

In ogni caso: posso risolvere questo problema solo perché so molto circa la natura dei compiti e la loro tempistica. Non sembra un difetto di progettazione che compiti sufficienti con il futuro ETA possano bloccare l'intero sistema? Se aspetto qualche ora, poi uccido e riavvio il lavoratore, riprende ancora una volta le prime 32 attività e si blocca, anche se a questo punto ci sono attività in coda che sono pronte per essere eseguite in questo momento. Non dovrebbe qualche componente essere abbastanza intelligente da guardare gli ETA e ignorare le attività che non sono eseguibili?

ADDENDUM: ora penso che il problema è un bug noto, quando RabbitMQ 3.3 viene utilizzato con sedano 3.1.0. Ulteriori informazioni qui: https://groups.google.com/forum/#!searchin/celery-users/countdown|sort:date/celery-users/FiAAESOzezA/499OH-pylacJ

Dopo l'aggiornamento a Celery 3.1.1, le cose sembrano migliori. L'attività A viene eseguita ogni ora (beh, dura per un paio d'ore) e pianifica le copie del task B. Quelle sembrano riempire il lavoratore: il numero di messaggi non confermati continua a crescere. Dovrò vedere se può crescere senza vincoli.

+1

Sì, RabbitMQ 3.3 rotto le cose. Ho avuto gli stessi problemi e Ask ha rilasciato velocemente Celery 3.1.11, Kombu 3.0.13 e librabbitmq 1.5.0. –

+0

Grazie, ho perso tutto il giorno cercando di capire cosa non andava finché non ho trovato questo! –

+0

Hai risolto questo ora? – nvartolomei

risposta

1

Sembra che questo è un problema che può essere risolto con il routing: http://celery.readthedocs.org/en/latest/userguide/routing.html

Quando si utilizza il routing, è possibile avere più code che sono popolate con diversi tipi di attività. Se si desidera che l'attività B non blocchi più un'attività A, è possibile trasformarli in code di lavoro separate con priorità diversa in modo che i lavoratori lavorino sulla coda grande piena di attività Bs ma quando arriva un'attività A viene richiamata dalla successiva disponibile lavoratore.

Il vantaggio di questo è che si può anche assegnare più lavoratori alle code pieni pesantemente e quei lavoratori tirerà solo dalla coda ad alto volume designato.

Problemi correlati