2012-02-12 12 views
13

Sto avendo un po 'di problemi a decidere qualsiasi cosa usi il multiprocessing o il sedano python o pp per la mia applicazione.Celery è efficiente su un sistema locale dato che il multiprocessing di Python è?

La mia app è molto pesante per la CPU ma al momento utilizza solo una CPU, quindi ho bisogno di distribuirla su tutti i cpus disponibili (cosa che mi ha fatto guardare la libreria multiprocessing di python) ma ho letto che questa libreria non è scalabile macchine se necessario. Al momento non sono sicuro se avrò bisogno di più di un server per eseguire il mio codice, ma sto pensando di eseguire il sedano localmente e quindi il ridimensionamento richiederebbe solo l'aggiunta di nuovi server invece del refactoring del codice (come sarebbe se usassi multiprocessing).

La mia domanda: questa logica è corretta? e c'è qualche negativo (prestazioni) nell'usare il sedano localmente (se si scopre che un singolo server con più core può completare il mio compito)? o è più consigliato usare il multiprocessing e svilupparlo in qualcos'altro dopo?

Grazie!

p.s. questo è per un progetto di apprendimento personale, ma forse un giorno mi piacerebbe lavorare come sviluppatore in un'azienda e voglio imparare come fanno i professionisti.

+0

Che cosa ti fa pensare che più CPU possano aiutare un'applicabilità da IO? Se la tua applicazione è legata all'IO, hai bisogno di più canali IO, non di CPU. –

+0

Di fronte alla parola scusa scusa ... è molto intensivo della CPU. Fondamentalmente è solo matematica in una grande ricorsione con molti input di dati. Sembrava un buon processo per distribuire – Lostsoul

+0

Ah - in tal caso, continua :) Hai bisogno di tolleranza di errore - ad esempio, cercando di utilizzare il calcolo volontario sparsi ovunque - o stai solo cercando di usare i computer in un laboratorio o un grappolo? –

risposta

4

In realtà non ho mai usato il sedano, ma ho utilizzato il multiprocesso.

Celery sembra avere diversi modi per inviare messaggi (attività) in giro, compresi i modi in cui si dovrebbe essere in grado di eseguire i lavori su macchine diverse. Quindi uno svantaggio potrebbe essere che il passaggio dei messaggi potrebbe essere più lento rispetto al multiprocessing, ma d'altra parte si potrebbe diffondere il carico su altre macchine.

Hai ragione che il multiprocesso può funzionare solo su una macchina. D'altro canto, la comunicazione tra i processi può essere molto veloce, ad esempio utilizzando la memoria condivisa. Inoltre, se è necessario elaborare grandi quantità di dati, è possibile leggere e scrivere facilmente dati da e sul disco locale e passare semplicemente i nomi dei file tra i processi.

Non so quanto bene Celery abbia a che fare con i fallimenti dei compiti. Ad esempio, l'attività potrebbe non finire mai in esecuzione, o potrebbe bloccarsi, oppure si potrebbe voler avere la possibilità di uccidere un'attività se non è terminata entro un certo limite di tempo. Non so quanto sarebbe difficile aggiungere supporto per questo se non è lì.

Il multiprocessing non viene fornito con tolleranza ai guasti, ma è possibile realizzarlo senza troppi problemi.

+2

Celery ha effettivamente un overhead maggiore rispetto all'utilizzo di multiprocessing.Pool direttamente, a causa del sovraccarico della messaggistica. Celery si occupa molto bene di fallimenti di attività in qualsiasi forma, supporta anche i limiti di tempo e molto, molto di più. Celery utilizza una versione migliorata del Pool multiprocessing (celery.concurrency.processes.pool.Pool), che supporta i limiti di tempo e corregge molti bug relativi all'esecuzione del Pool come servizio (vale a dire in esecuzione per sempre) e bug relativi allo shutdown. Alcune persone usano la versione del pool di Celery. – asksol

+0

Alcuni link: http://docs.celeryproject.org/en/latest/userguide/workers.html#time-limits http://docs.celeryproject.org/en/latest/userguide/workers.html#revoking-tasks Opzioni pool: http://docs.celeryproject.org/en/latest/internals/reference/celery.concurrency.processes.pool.html#celery.concurrency.processes.pool.Pool http://docs.celeryproject.org/ it/latest/internals/reference/celery.concurrency.processes.pool.html # celery.concurrency.processes.pool.Pool.apply_async – asksol

+2

È anche possibile distribuire il lavoro tra le macchine utilizzando solo la multiprocessing, ma non lo consiglierei. Rendere la qualità della produzione probabilmente richiederebbe uno sforzo considerevole e Celery ha già una comunità che sta risolvendo questi problemi. – asksol

17

Ho appena terminato un test per decidere la quantità di sedano aggiunta come overhead su multiprocessing.Pool e gli array condivisi. Il test esegue il filtro wiener su un array uint16 (292, 353, 1652). Entrambe le versioni usano lo stesso chunking (all'incirca: dividono le 292.353 dimensioni per la radice quadrata del numero di CPU disponibili). Sono state provate due versioni di sedano: una soluzione invia i dati decapitati l'altra apre il file di dati sottostante in ogni lavoratore.

Risultato: sul mio 16 core i7 CPU occupa circa 16s, multiprocessing.Pool con array condivisi circa 15s. Trovo questa differenza sorprendentemente piccola.

L'aumento della granularità aumenta ovviamente la differenza (il sedano deve passare più messaggi): il sedano richiede 15 s, multiprocessing.Pool richiede 12 secondi.

Prendere in considerazione che i lavoratori del sedano erano già in esecuzione sull'host mentre i lavoratori della piscina sono biforcati ad ogni corsa.Io non sono sicuro di come ho potuto iniziare multiprocessing piscina all'inizio da quando mi passa le matrici condivise nel inizializzatore:

with closing(Pool(processes=mp.cpu_count(), initializer=poolinit_gen, initargs=(sourcearrays, resarrays))) as p: 

e solo i resarrays sono protetti bloccando.

+1

Sono riuscito a separare la configurazione del pool dalla misurazione, ma ciò ha fatto quasi nessuna differenza (come previsto, la forcella è economica). Provare con un altro dataset (276, 385, 3821): sedano tramite pickled transfer 38s, multiprocessing.Pool 27s. Sinceramente trovo il sedano molto più comodo con cui lavorare e può delegare naturalmente l'elaborazione ad altre macchine nel caso in cui il tempo di elaborazione sia molto più lungo del tempo di trasferimento. Su una singola macchina, la differenza di prestazioni diventa evidente solo per i set di dati di grandi dimensioni. –

Problemi correlati