2013-04-16 19 views
51

Ho appena scoperto l'opzione di configurazione CELERYD_PREFETCH_MULTIPLIER (docs). Il valore predefinito è 4, ma (credo) voglio il prefetch off o il più basso possibile. Ho impostato a 1 ora, che è abbastanza vicino a quello che sto cercando, ma ci sono ancora alcune cose che non capisco:Informazioni sul prefetch delle attività di sedano

  1. Perché questo è prefetching una buona idea? Non vedo davvero una ragione per questo, a meno che non ci sia molta latenza tra la coda dei messaggi e gli operatori (nel mio caso, sono attualmente in esecuzione sullo stesso host e, nel peggiore dei casi, potrebbero eventualmente essere eseguiti su host diversi negli stessi dati centro). La documentazione menziona solo gli svantaggi, ma non riesce a spiegare quali sono i vantaggi.

  2. Molte persone sembrano impostare questo a 0, aspettandosi di essere in grado di disattivare il prefetching in quel modo (una supposizione ragionevole a mio parere). Tuttavia, 0 significa prefetching illimitato. Perché qualcuno vorrebbe mai un prefetching illimitato, non elimina del tutto la concorrenza/asincronicità che ha introdotto una coda di attività in primo luogo?

  3. Perché il precaricamento non può essere disattivato? Potrebbe non essere una buona idea per le prestazioni disattivarlo nella maggior parte dei casi, ma esiste una ragione tecnica per cui ciò non è possibile? O è solo non implementato?

  4. A volte questa opzione è collegata a CELERY_ACKS_LATE. Per esempio. Roger Hu writes «[...] spesso ciò che [gli utenti] vogliono veramente è che un lavoratore si riservi il maggior numero di compiti quanti sono i processi figli. Ma questo non è possibile senza abilitare i riconoscimenti tardivi [...] »Non capisco come queste due opzioni siano collegate e perché non sia possibile senza l'altra. Un'altra menzione della connessione può essere trovata here. Qualcuno può spiegare perché le due opzioni sono collegate?

risposta

20
  1. Prefetching può migliorare le prestazioni. I lavoratori non devono attendere il successivo messaggio da parte di un broker per l'elaborazione. Comunicare con un broker una volta e l'elaborazione di molti messaggi offre un guadagno in termini di prestazioni. Ottenere un messaggio da un broker (anche da uno locale) è costoso rispetto all'accesso alla memoria locale. I lavoratori sono anche permesso di confermare i messaggi in lotti

  2. Prefetching impostato a zero significa "nessun limite specifico" piuttosto che illimitato

  3. Impostazione prefetching a 1 è documentata per essere equivalente a spegnerlo, ma questo potrebbe non sempre essere il caso (vedi https://stackoverflow.com/a/33357180/71522)

  4. Il prefetching consente di accettare messaggi in batch. CELERY_ACKS_LATE = TRUE impedisce riconoscendo i messaggi quando raggiungono ad un lavoratore

+0

Grazie. 2) Ok, ma perché qualcuno dovrebbe voler "nessun limite specifico"? 3) Sono abbastanza sicuro di vedere ancora i messaggi di "Got task from broker" prima che l'attività corrente sia finita. –

+1

AFAIK, l'impostazione del precaricamento su 1 è ** non ** equivalente allo spegnimento. È il valore più basso possibile (pur non hackerando il codice sorgente) per prefetch, che, a sua volta, è il numero di CPU/core nella macchina corrente. –

+1

@RonKlein Non è il numero di CPU/core, è il numero di lavoratori di Celery che hai definito (che in alcuni casi può essere lo stesso, ma di solito non lo è). Inoltre, se ogni lavoratore sta eseguendo il precaricamento di una singola attività, quindi eseguendola, quindi prelettura un'altra, ciò equivale a disattivare il precaricamento, quindi IMHO la tua affermazione non è corretta. (Il sistema deve sempre eseguire il precaricamento di tutte le attività quanti sono i lavoratori se vuole mantenere tutti i lavoratori alimentati con le attività.) – nitwit

13

Solo un avvertimento: a partire dal mio test con il broker Redis + sedano 3.1.15, tutti i consigli che ho letto di pertinenza CELERYD_PREFETCH_MULTIPLIER = 1 disabilitazione prefetching è palesemente falso

per dimostrare questo:

  1. Set CELERYD_PREFETCH_MULTIPLIER = 1
  2. in coda 5 compiti che sarà ogni necessari alcuni secondi (ex, time.sleep(5))
  3. Inizia a guardare la lunghezza della coda compito in Redis: watch redis-cli -c llen default

  4. Inizio celery worker -c 1

  5. Si noti che la lunghezza della coda in Redis immediatamente scenderà da 5 a 3

CELERYD_PREFETCH_MULTIPLIER = 1non impedisce prefetching, limita semplicemente il prefetching per 1 compito per coda.

-Ofair, despite what the documentation says, anche non impedisce il prefetching.

In mancanza di modifica del codice sorgente, non ho trovato alcun metodo per disattivare completamente il precaricamento.

+0

Come altre risposte hanno menzionato se si imposta anche ' CELERY_ACKS_LATE = 1', allora disabiliterai efficacemente il prefetching. – jodag

5

Non posso commentare le risposte di David Wolever, poiché il mio stack non è abbastanza alto. Quindi, ho definito il mio commento come una risposta poiché mi piacerebbe condividere la mia esperienza con Celery 3.1.18 e un broker Mongodb. Sono riuscito a smettere di prefetching con il seguente:

  1. aggiungere CELERYD_PREFETCH_MULTIPLIER = 1 alla configurazione del sedano
  2. aggiungere CELERY_ACKS_LATE = True alla configurazione del sedano
  3. Inizia lavoratore sedano con le opzioni: --concurrency=1 -Ofair

Lasciando CELERY_ACKS_LATE al di default, il lavoratore continua a prefetcher. Proprio come l'OP, non comprendo completamente il collegamento tra prefetch e late acks. Capisco ciò che David dice "CELERY_ACKS_LATE = True impedisce di riconoscere i messaggi quando raggiungono un lavoratore", ma non riesco a capire perché i tardivi acks sarebbero incompatibili con prefetch. In teoria un prefetch consentirebbe comunque di ack late right - anche se non è codificato come tale in sedano?

11

Vecchia domanda, ma aggiungendo ancora la mia risposta nel caso in cui aiuti qualcuno. La mia comprensione da alcuni test iniziali è stata la stessa di quella di David Wolever. Ho appena provato questo più in sedano 3.1.19 e -Ofair funziona. Solo che non è pensato per disabilitare il precaricamento a livello del nodo di lavoro. Ciò continuerà ad accadere. L'uso di -Ofair ha un effetto diverso a livello di pool worker. In sintesi, per disabilitare completamente prefetch, fare questo-

  1. Impostare CELERYD_PREFETCH_MULTIPLIER = 1
  2. Impostare CELERY_ACKS_LATE = True ad un livello o un'attività livello globale
  3. Usa -Ofair mentre a partire lavoratori
  4. Se si imposta la concorrenza a 1, quindi il passaggio 3 non è necessario. Se si desidera una maggiore concorrenza , il passaggio 3 è essenziale per evitare di eseguire il backup di in un nodo che potrebbe eseguire attività a esecuzione prolungata.

Aggiunta qualche dettaglio in più:

ho trovato che il nodo lavoratore sempre prefetto per impostazione predefinita. Puoi controllare solo quante attività esegue il prefetch utilizzando CELERYD_PREFETCH_MULTIPLIER. Se impostato su 1, eseguirà solo il precaricamento di tutte le attività del numero di worker del pool (concurrency) nel nodo. Quindi se tu avessi concorrenza = n, le attività massime prefetchate dal nodo saranno n.

Senza l'opzione -Ofair, quello che è successo per me era che se uno dei processi di pool control eseguiva un'attività a esecuzione prolungata, gli altri worker nel nodo interrompevano anche l'elaborazione delle attività già precaricate dal nodo. Usando -Ofair, quello è cambiato. Anche se uno degli addetti al nodo stava eseguendo attività a esecuzione prolungata, altri non avrebbero interrotto l'elaborazione e avrebbero continuato a elaborare le attività precaricate dal nodo. Quindi vedo due livelli di prefetching. Uno a livello di nodo di lavoro. L'altro a livello di singolo lavoratore. L'utilizzo di -Ofair per me sembrava disabilitarlo a livello di lavoratore.

Come è correlato ACKS_LATE? ACKS_LATE = True significa che l'attività verrà confermata solo quando l'attività ha esito positivo. In caso contrario, suppongo che accada quando viene ricevuto da un lavoratore. In caso di prefetch, l'attività viene prima ricevuta dall'operatore (confermata dai log) ma verrà eseguita in un secondo momento. Ho appena realizzato che i messaggi prefeteched vengono visualizzati con messaggi non riconosciuti in rabbitmq. Quindi non sono sicuro che l'impostazione su True sia assolutamente necessaria. Abbiamo comunque avuto i nostri compiti impostati in questo modo (late ack) per altri motivi.

+0

Grazie per aver ancora contribuito a questa domanda! Potresti aggiungere qualche dettaglio in più? Ad esempio, stai scrivendo "-Ofair" ha un "effetto diverso", ma non come l'effetto è diverso. Inoltre, stai richiamando 'CELERY_ACKS_LATE', come altri prima, ma finora nessuno è riuscito a spiegarmi cosa ha a che fare questo attributo con la disattivazione del precaricamento. –

+0

Ho avuto lo stesso problema, in esecuzione con un backend redis.Avevo 4 task concorrenti in esecuzione e quando uno iniziava a impiccarsi gli altri aspettavano che finisse quello (non lo faceva) - Uccidendo quel lavoratore avrebbe poi permesso agli altri di riprendere. Ho già avuto 'prefetch = 1, celery_acks = True' e quando ho aggiunto' -Ofair' ha risolto il problema in cui stavano aspettando il lavoratore appeso. Sfortunatamente il problema dei lavoratori pendenti non è ancora stato risolto per me e quindi tutti gli addetti alla fine si bloccano, ma almeno non lo fanno più nello stesso momento. – JiminyCricket

Problemi correlati