2013-03-06 9 views
5

Vorrei implementare un sistema di esecuzione del lavoro distribuito con sedano. Dato che rabbitMQ non supporta le priorità e ho dolorosamente bisogno di questa funzione, mi sono rivolto a sedici + redis.Priorità attività in sedano con redis

Nella mia situazione, le attività sono strettamente correlate all'hardware, ad esempio, l'attività A può essere eseguita solo su Worker 1 poiché solo il PC di Worker 1 ha l'hardware necessario. Ho impostato la CONCURRENCY di ciascun lavoratore su 1 in modo che un lavoratore esegua solo un'attività ogni volta. Ogni compito richiede circa 2 minuti.

implementare la funzione priorità, innanzi tutto provato ad aggiungere priority argomento quando si chiama apply_async(), per esempio apply_async(priority=0) e apply_async(priority=9). In questo test ho lanciato solo un lavoratore con COCURRENCY = 1 e ho avviato 10 compiti uno per uno con priorità diverse. Mi aspettavo di vedere le attività avviate da apply_async(priority=0) verranno eseguite in priorità, ma purtroppo sono appena iniziato come l'ordine di espulsione.

Quindi provo a fare un po 'di lavoro. Ho clonato ogni attività, quindi per ognuna ho task_high e task_low, decorato da @celery.task(priority=0) e @celery.task(priority=1). Poi ho fatto lo stesso test come sopra, questa volta è stato meglio, quando l'ordine di kick-off è "HH-LLLL-HHHH", l'ordine reale risulta essere "HH-L-H-H-L-H-L-L-H". Suppongo che i redis abbiano svolto un lavoro di pianificazione e bilanciamento qui.

Ma questo non può ancora soddisfare le mie aspettative. Spero di ottenere un ordine come "HHHHHH-LLLL", perché per alcune attività ho solo una macchina adeguata con l'hardware necessario e spero che l'attività ad alta priorità venga eseguita il prima possibile.

Ho cercato altri lavori in Internet, ad esempio utilizzando due code, una per le attività con priorità alta e l'altra per priorità bassa, e utilizzando 2 macchine per la prima e 1 macchina per quest'ultima. Ma dal momento che il mio hardware è abbastanza limitato, questo non funziona per me.

Potrebbe fornire qualche suggerimento?

risposta

13

Il trasporto di Celery Redis rispetta il campo prioritario, ma lo stesso Redis non ha alcuna nozione di priorità.

Il supporto prioritario viene implementato creando n elenchi per ogni coda e utilizzando tale ordine nel comando BRPOP. Qui dico n perché anche se ci sono 10 (0-9) livelli di priorità, questi sono consolidati in 4 livelli per impostazione predefinita per risparmiare risorse. Ciò significa che una coda denominata celery sarà davvero essere diviso in 4 code:

['celery0', 'celery3`, `celery6`, `celery9`] 

Se volete più livelli di priorità è possibile impostare l'opzione priority_steps trasporti:

BROKER_TRANSPORT_OPTIONS = { 
    'priority_steps': list(range(10)), 
} 

Detto questo, si noti che questo non sarà mai all'altezza delle priorità implementate a livello di server e potrebbe essere approssimativo nel migliore dei casi. Ma potrebbe comunque essere buono per la tua applicazione.

+0

Grazie per i dettagli, ma cosa potrei fare per ottenere un ordine come voglio? Dovrei semplicemente cambiare il 'priority_steps'? –

+0

Avrai appena provato. Con i passaggi di priorità predefiniti, quelli 0 e 1 verranno consolidati solo in 0. – asksol

+0

OK grazie, ho provato con priorità 0 per task alto e priorità 9 per task basso, ora sembra molto meglio, anche se a volte alcuni task con priorità 9 funzionano ancora prima di quelli con priorità 0. Non so se c'è qualcosa sbagliato con le mie configurazioni o è redis che ha fatto un po 'di lavoro di bilanciamento. –