Quanti processi devo specificare in un WSGIDaemonProcess mentre eseguo Django tramite mod_wsgi?


23

Diciamo che ho 2 siti (Superuser e Serverfault) in esecuzione dal proprio host virtuale Apache su una casella. I 2 siti sono basati su Django e funzionano su Apache con mod-wsgi. Un tipico file di configurazione per uno dei siti sarà simile al seguente:

WSGIDaemonProcess serverfault.com user=www-data group=www-data processes=5

L'host è una macchina linux con 4 GB di RAM con Ubuntu. Qualcuno può suggerire il numero di processi che dovrei specificare sopra per i miei 2 siti? Supponiamo che abbiano lo stesso traffico degli attuali siti Superuser e Serverfault.

Risposte:


22

Ebbene, la quantità di traffico fanno gli attuali siti di superutente e Serverfault hanno? Ipotetici non sono molto utili se non hanno abbastanza informazioni per facilitare la risposta ...

Il conteggio dei processi nel caso peggiore dovrebbe essere il numero massimo di richieste al secondo che il sito deve essere in grado di gestire, diviso per il numero di richieste al secondo che un processo può gestire se tutte quelle richieste vengono fatte all'azione più lenta (quindi il reciproco del tempo di elaborazione di tale azione). Aggiungi qualsiasi fattore di sfumatura che ritieni appropriato, in base all'intervallo di confidenza del tuo req / sec e alle misurazioni del tempo.

Il conteggio medio dei casi è lo stesso, ma dividi il req / sec per la media ponderata delle cifre delle tue richieste al secondo per ogni azione (il peso è la percentuale di richieste che prevedi di colpire quella particolare azione). Ancora una volta, i fattori di fondente sono utili.

Il limite superiore effettivo di quanti processi è possibile eseguire sulla macchina è dettato dalla quantità di memoria superiore richiesta da ciascun processo; eseguire lo spooling di un processo, quindi eseguire una varietà di azioni affamate di memoria (quelle che recuperano ed elaborano molti dati, in genere) su di esso con un set di dati realistico (se si utilizza solo un set di dati giocattolo per test, diciamo 50 o 100 righe, quindi se una delle tue azioni recupera e manipola ogni riga della tabella, non sarà una buona misura per quando la tabella aumenta fino a 10.000 righe) per vedere a cosa si esaurisce l'uso della memoria. È possibile limitare artificialmente l'utilizzo della memoria per processo con uno script che raccoglie i lavoratori che raggiungono una determinata soglia di utilizzo della memoria, con il rischio di causare problemi fastidiosi se si imposta tale soglia troppo bassa.

Una volta che hai la tua figura di utilizzo della memoria, deduci una certa quantità di memoria per l'overhead del sistema (mi piacciono 512 MB), deduci un mucchio di più se hai altri processi in esecuzione sullo stesso computer (come un database), e quindi un po 'di più per assicurarti di non esaurire lo spazio nella cache del disco (dipende dalla dimensione del set di lavoro del disco, ma di nuovo andrei con non meno di 512 MB). Questa è la quantità di memoria che dividi per l'utilizzo della memoria per processo per ottenere il limite massimo.

Se il numero di processi necessari per gestire il carico di picco è maggiore del numero di processi che è possibile inserire nella confezione, sono necessari più computer (o per spostare il database su un altro computer, nel caso più semplice).

Eccoti qui, diversi anni di esperienza nel ridimensionamento di siti Web distillati in un piccolo e semplice post SF.


Un altro fattore importante per il numero di processi / thread è il tempo necessario per gestire le singole richieste e la diffusione complessiva su tutte le lunghezze di tempo possibili. In altre parole, quante richieste alla volta devono essere gestite che richiedono tempi di risposta superiori alla media. Pertanto, non è così semplice come solo richieste teoriche / sec poiché l'impatto di quelle richieste più lunghe può essere significativo e imporre indebitamente i parametri di configurazione generali. FWIW mod_wsgi 3.0 includerà alcune raccolte di statistiche integrate per cercare di acquisire dati al riguardo per facilitare la configurazione.
Graham Dumpleton,

@Graham: rileggi la mia risposta, l'ho coperta in qualche dettaglio. Richieste / sec è solo il reciproco del tempo di risposta ed è più facile dividere per un numero intero req / sec piuttosto che moltiplicare per un decimale.
womble

Non puoi però concentrarti solo sulla risposta del caso peggiore, né solo sulla media per quella materia. Deve essere ponderato secondo modalità basate sulla percentuale di richieste che rientrano in periodi di tempo, vale a dire la diffusione tra tutti i tempi possibili presi. Se prendessi davvero il tuo tempo di risposta nel caso peggiore, ti verrebbero fuori requisiti irrealistici. Il problema è davvero difficile sapere quale formula usare. Questo è il motivo per cui in mod_wsgi 3.0 ci saranno raccolte statistiche integrate che guardano all'utilizzo dei thread e per quale percentuale in base al conteggio e al tempo in cui un numero qualsiasi di thread è in uso contemporaneamente.
Graham Dumpleton,

3
Il problema è forse che stai osservando i processi solo quando sono preoccupato di come i thread che ogni processo utilizza contano e non è così semplice. In altre parole, quella direttiva WSGIDaemonProcess indica 5 processi in cui ogni processo è di default usando 15 thread. Per quanto ho letto nella tua descrizione, sta assumendo processi a thread singolo. In caso contrario, indicami come il tuo modello soddisfa le discussioni più i problemi di contesa / ridimensionamento in GIL. Quindi, qualifica che la tua descrizione è valida solo per i processi a thread singolo e non discuterò.
Graham Dumpleton,

2
"Multithreaded-Apache + multiprocess-wsgi" non è forse la soluzione migliore fino a quando non sei sicuro al 99% che il tuo codice Python e tutte le dipendenze siano thread-safe?
Tomasz Zieliński,

9

La risposta di Womble è fantastica, anche se un po 'difficile da capire e applicare per gli inesperti. Vorrei fornire alcuni numeri empirici e un confronto tra applicazioni "contenuto semplice" e "e-commerce".

Non c'è molto materiale sull'impostazione di diversi casi d'uso in relazione alla loro configurazione appropriata di mod_wsgi, quindi spero che sia giusto usare un po 'di prosa qui.

A) Siti CMS e micrositi

Gestiamo diversi siti Web di clienti, molti dei quali principalmente siti di contenuti o micro siti che ospitano django CMS, alcuni moduli personalizzati e talvolta sedano per attività in background pianificate. Questi siti non hanno fame di risorse, molti di essi funzionano felicemente in parallelo su un singolo Intel Xeon a 4 core con 32 GB di RAM. Ecco la configurazione che utilizziamo per ciascuno di questi tipi di siti:

WSGIDaemonProcess example.com user=www-data processes=2 maximum-requests=100

Sto parlando di circa 40 siti su un singolo server, molti dei quali con il loro sito di gestione temporanea in esecuzione in standby. Con 2 processi (con 15 thread ciascuno, per impostazione predefinita) i siti sono benestanti, sebbene limitati nella loro capacità di allocare le risorse del server. Il motivo per cui questa configurazione è sufficiente può essere giustificato dalla semplice natura dell'applicazione (CMS): per completare una richiesta non è mai necessario attendere più di un paio di millisecondi. Apache rimarrà sempre rilassato, così come il carico della CPU.

B) Siti di e-commerce

I siti più complessi che realizziamo sono caratterizzati da operazioni locali ancora poco costose dal punto di vista computazionale ma da dipendenze esterne (ad es. Servizi Web che forniscono dati di prenotazione) che sono costose in termini di tempo di transazione. Le operazioni con richieste esterne occupano thread per un tempo molto più lungo, quindi sono necessari più thread per soddisfare lo stesso numero di utenti (rispetto a un semplice sito CMS dall'alto). Ancora peggio, i thread vengono occasionalmente bloccati quando un servizio esterno non può rispondere immediatamente a una richiesta, a volte per un paio di secondi. Questo può portare allo sgradevole effetto collaterale che i thread che inseriscono le richieste nella stessa coda di servizio, fino a quando tutti i thread mod_wsgi disponibili vengono esauriti e bloccano l'attesa.

Per quegli scenari abbiamo cercato di utilizzare i 6processi senza vedere molte differenze e abbiamo finito per 12vedere un aumento incomparabile delle prestazioni e della stabilità operativa:

WSGIDaemonProcess example.com user=www-data processes=12 maximum-requests=100

Alcuni semplici test di carico con 150 e 250 utenti paralleli sono gestiti facilmente dal sito rimanendo ben reattivi (mentre con i 2processi il sito è inutilizzabile per soddisfare 50 utenti in parallelo). Il 2 CPU 6 Core Intel Xeon con 32 GB di RAM funziona ben al di sotto del 25% di utilizzo della CPU con quel carico, l'utilizzo della RAM rimane quasi costante anche a meno del 25%. Tieni presente che qui utilizziamo una macchina dedicata solo per un singolo sito, quindi non ruberemo risorse di cui altri siti potrebbero aver bisogno.

Conclusione

L'uso di un numero più elevato di processi è un compromesso tra consentire ad Apache di utilizzare o meno le risorse di sistema disponibili. Se si desidera mantenere un sistema server stabile (non un sito Web!) In condizioni di "attacco", mantenere basso il numero. Se vuoi che Apache ti aiuti usando le risorse di sistema (CPU, RAM) quando necessario, scegli un numero più alto. Quanto in alto puoi calcolare in qualche modo come indicato nella risposta accettata sopra, ed è in definitiva limitato dalla potenza della CPU e dalla RAM disponibili.

(PS: tengo la sezione ConfigurationDirectives del wiki del progetto modwsgi sotto il mio cuscino per la lettura in background simile ad Apache. Assicurati anche di capire e monitorare le connessioni aperte del tuo server Apache .)


Ottimo post, ma perché non imposti il ​​conteggio dei thread? Dal momento che GIL di Python nega molti dei vantaggi dei thread, suppongo che vorresti avere più processi rispetto ai thread, ma c'è qualche vantaggio nello specificare il numero di thread?
Cerin,

Il numero predefinito di threadsè 15 secondo la documentazione . Non penso che ci sia un vantaggio nel specificarlo esplicitamente. In effetti, ricordo di averlo lasciato fuori per un motivo: c'erano alcuni post su SO o una parte di alcuni documenti che raccomandavano di omettere il valore per evitare effetti collaterali (lo so, sembra strano). Sfortunatamente, non trovo quella fonte ora. Per il resto della tua domanda (GIL) probabilmente sei più esperto di me, scusa.
Peterino,

Grazie per questa configurazione empirica. Tuttavia, You should never use maximum-requests in a production system unless you understand the implications and have a specific temporary need.
tieni
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.