> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Il 06/12/2011 18:34, Giampaolo Rodolà ha scritto: >> Il 03 dicembre 2011 16:23, Manlio Perillo <manlio.peri...@gmail.com> ha >> scritto: >>>> Una cosa di questo tipo non avrebbe ugualmente funzionato? >>>> >>>> # pseudo codice >>>> import multiprocessing >>>> from somehttpd import HTTPServer >>>> >>>> CPUS = multiprocessing.cpu_count() >>>> server = HTTPServer() >>>> # create child processes to act as workers >>>> for x in range(CPUS - 1): >>>> Process(target=server.serve_forever).start() >>>> # main process also acts as a worker >>>> server.serve_forever() >>>> >>>> >>>> Se si, ti saresti evitato l'onere di ascoltare su porte multiple e >>>> ovviamente tutta la complessità aggiuntiva che ne deriva. >>>> >>> >>> Questo è essenzialmente l'approccio usato da Nginx. >>> >>> Però c'è un dettaglio subdolo: con questo metodo ciascun processo >>> figlio >>> chiama la accept sullo stesso file descriptor ereditato dal padre e ci >>> potrebbero essere dei problemi subdoli. >>> >>> Ad esempio il problema chiamato "thundering herd" oppure (ma su questo >>> non riesco a trovare dei riferimenti, l'ho letto dall'autore di Nginx) >>> il sistema operativo potrebbe **non** distribuire il carico equamente >>> su >>> tutti i sotto processi. >>> >>> >>> Ciao Manlio >> >> Riusciresti a darmi qualche dettaglio in più? > > Per il "Thundering herd problem", trovi una breve descrizione su > Wikipedia: > http://en.wikipedia.org/wiki/Thundering_herd_problem > > Vedi anche: > http://www.citi.umich.edu/projects/linux-scalability/reports/accept.html > > > Il problema è menzionato anche nel libro "UNIX Network Programming". > In particolare, oltre al problema di prestazioni che per pochi processi > non dovrebbe essere preoccupante, c'è un altro problema con quello che > fai: chiamare accept sullo stesso file descriptor ereditato potrebbe > **non** funzionare su alcuni sistemi; in questi casi hai bosogno di > serializzare la chiamata con un lock o mutex (che è quello che, > opzionalmente, fa Nginx [1]). > > Ti consiglio di fare dei test e di documentarti meglio (io non so > nemmeno cosa è cambiato in versioni recenti di Linux). >
accept() non e' piu' soggetta al thundering herd da un po', mentre epoll_wait() lo e', e pure di brutto. Dai test effettuati per uWSGI e' comunque meglio avere il thundering herd (basta saperlo gestire nel codice) che un locking costante quando il numero di epoll_wait() in ascolto non supera (o supera di poco) il numero di core cpu. Se invece il numero e' abnorme (ad esempio quando si va in preforking+multithread) su Linux e' meglio il locking (per lo meno dei thread all'interno dello stesso processo) Ad oggi ne' io ne' i ragazzi di unicorn (server ruby di cui gunicorn e' il porting in python) abbiamo rilevato un impatto del thundering herd tale da doverlo gestire diversamente. Di idea completamente opposta i ragazzi di passenger che invece preferiscono gestire tutto in user space con una porta aperta per ogni processo. Evidentemente si sentono stra-sicuri del loro load-balancer interno, o sanno qualcosa che io non so :) -- Roberto De Ioris http://unbit.it _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python