C'è un modo migliore per servire i risultati di un costoso, bloccando processo pitone su HTTP?

StackOverflow https://stackoverflow.com/questions/1929681

  •  20-09-2019
  •  | 
  •  

Domanda

Abbiamo un servizio web che serve piccoli segmenti arbitrari di un inventario fisso di file MP3 di grandi dimensioni. I file MP3 vengono generati on-the-fly da un'applicazione pitone. Il modello è, fare una richiesta GET a un URL che specifica quali segmenti si desidera, ottenere un flusso audio/mpeg in risposta. Questo è un processo costoso.

Stiamo usando Nginx come il gestore di richieste di front-end. Nginx si prende cura di risposte di cache per le richieste comuni.

Inizialmente abbiamo provato ad utilizzare Tornado sul back-end per gestire le richieste di Nginx. Come ci si aspetterebbe, l'operazione MP3 blocco mantenuto Tornado dal fare il suo dovere (I / O asincrono). Così, siamo andati multithread, che ha risolto il problema di blocco, ed eseguito abbastanza bene. Tuttavia, ha introdotto una condizione di competizione sottile (sotto carico mondo reale) che non siamo stati in grado di diagnosticare o riprodurre ancora. La condizione di competizione corrompe la nostra produzione di MP3.

Così abbiamo deciso di impostare la nostra applicazione come un semplice gestore WSGI dietro Apache / mod_wsgi (ancora w / Nginx in attacco). Questo elimina il problema di blocco e la condizione di competizione, ma crea un carico a cascata (vale a dire Apache crea troppi processses) sul server in condizioni reali. Stiamo lavorando sulla messa a punto Apache / mod_wsgi in questo momento, ma ancora in una fase di prova ed errore. (Aggiornamento:.. Abbiamo commutata al Tornado, vedi sotto)

Infine, la domanda: ci manca qualcosa? C'è un modo migliore per servire le risorse della CPU-costosi su HTTP?

Aggiornamento: grazie all'articolo informato di Graham, sono abbastanza sicuro che questo è un problema di messa a punto di Apache. Nel-frattempo, siamo andati di nuovo a usando Tornado e stanno cercando di risolvere il problema dei dati-corruzione.

Per coloro che sono stati così pronti a gettare più di ferro il problema, Tornado e un po 'di multi-threading (nonostante il problema dell'integrità dei dati introdotto da filettatura) gestisce il carico accettabile su una piccola (single core) istanza Amazon EC2.

È stato utile?

Soluzione

Si stanno facendo l'errore di usare la modalità integrata di Apache / mod_wsgi? Read:

http: // blog .dscpl.com.au / 2009/03 / load-punte-e-eccessiva-memory-usage.html

Assicurarsi di utilizzare modalità demone se si utilizza Apache / mod_wsgi.

Altri suggerimenti

Hai provato La deposizione delle uova ? Si tratta di un server WSGI con un assortimento flessibile delle modalità di threading.

Si potrebbe prendere in considerazione un sistema di accodamento con metodi di notifica AJAX.

Ogni volta che c'è una richiesta per la vostra risorsa costosa, e che la risorsa deve essere generato, aggiungere la richiesta alla coda (se non è già presente). Tale operazione messa in coda dovrebbe restituire un ID di un oggetto che è possibile interrogare per ottenere il suo stato.

Avanti si deve scrivere un servizio in background che gira su thread di lavoro. Questi lavoratori semplicemente annullare l'accodamento della richiesta, generano i dati, quindi salva la posizione del dati nell'oggetto richiesta.

La pagina web può fare chiamate AJAX al server per scoprire i progressi della generazione e per dare un collegamento al file una volta che è disponibile.

Questo è il modo in siti di media grande opera - quelli che hanno a che fare con il video in particolare. Potrebbe essere eccessivo per il vostro lavoro MP3 comunque.

In alternativa , guardare in esecuzione di un paio di macchine per distribuire il carico. Le discussioni che su Apache saranno ancora bloccare, ma atleast non sarà consumare le risorse del server web.

Si prega di definire "a cascata di carico", in quanto non ha senso comune.

Il più probabile problema sta per essere se si sta eseguendo troppi processi Apache.

Per un carico come questo, assicurarsi che si sta utilizzando il mpm prefork, e assicurarsi che si te sta limitando a un numero appropriato di processi (non meno di uno per CPU, non più di due).

Sembra che si sta facendo le cose giuste - manca solo la potenza della CPU:? Si può determinare che cosa è il carico della CPU nel processo di generazione di questi MP3

Credo che la prossima cosa che devi fare quello che c'è da aggiungere altro hardware per rendere i MP3 su altre macchine. O che o trovare un modo per fornire pre-renderizzati MP3 (forse si può cache all'interno alcuni dei vostri mezzi?)

A proposito, il ridimensionamento per il web è stato il tema di una conferenza Keynote di Jacob Kaplan-Moss su PyCon Brasil quest'anno, ed è ben lungi dall'essere un problema chiuso. Lo stack di tecnologie si ha la necessità di gestire è piuttosto impressionabile - (non sono riuscito a trovare una copia online o f la presentazione, anche se - Mi spiace per quello)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top