[Python] web: sync vs. async

Daniele Varrazzo piro a develer.com
Lun 5 Dic 2011 09:46:15 CET


On Mon, 5 Dec 2011 01:11:22 +0100, Alessandro Dentella wrote:
> Grazie Daniele per i molti stimoli, ma vorrei capire meglio...
>
> On Fri, Dec 02, 2011 at 08:44:26PM +0000, Daniele Varrazzo wrote:
>> >Comincerei a pensare di usare un server non bloccante (e magari le
>> >greenlet per avere una API familiare) *solo* se l'applicazione deve
>> >scalare su migliaia di richieste ed è fondamentale non sprecare
>> >risorse
>> >su processi/threads.
>>
>> I thread non sono una faccenda di risorse sprecate su Python: sono
>> una faccenda di lock contention, e scala maledettamente male: nelle
>> poche decine, anche se la macchina permetterebbe ben altro. Nessuno
>
> Se il problema è la lock contention, non vedo come una soluzione 
> asincrona
> migliori o scali meglio. Se due chiamate devono contendersi uno 
> stesso dato
> dovrò sempre attuare le stesse strategie anche in modalità
> asincrona. Sbaglio?

Il lock di cui parlo che viene conteso è il gil. Alcuni studi (recenti, 
googlabile) hanno mostrato che una situazione di thread bloccati in io 
con thread impegnati con la CPU l'interprete si comporta peggio di 
quanto sperato. In ambienti asincroni, con i singoli lavoratori 
(greenlet o callback) risvegliati dal kernel quando l'I/O è completo 
l'utilizzo della CPU è ottimale.

> Nel caso per cui ho fatto partire questa discussione poi ho 
> concorrenza
> molto limitata (in pratica solo con chiamate generate dalla stessa 
> pagina
> web, non da altri utenti)
>
>> dei nostri programmi (sia web che altro, ma con necessità di
>> concorrenza) è "sopravvissuto al proprio successo" senza venire
>> sbudellato (chi ribasato su greenlet, chi riscritto in erlang...) Il
>> sito web di cui ho parlato oggi ha pochi clienti ma è molto
>> cpu-intensive e nei giorni di maggiore attività non reggeva 80
>> clienti connessi prima di splittarlo.
>>
>> Il problema di Alessandro non è quello di scalare: ha verificato che
>> la sua macchina è praticamente inattiva per tutto il tempo. Se
>> risolve il problema del database che lo blocca dovrebbe stare a
>> cavallo. Poi non è che si sia prodigato in dettagli: magari il
>> blocco è nel db che offre poche connessioni, non si sa se il db sia
>> sulla stessa macchina... un po' di lavoro deve farlo anche lui, non
>> possiamo mica debuggare con la telepatia, no? :) Magari quella cosa
>> di psycopg + async funziona bene: in fondo quella di twisted pare
>> vada. E non lo costringerebbe a scrivere il programma da zero.
>
> La soluzione che hai indicato -il modulo momoko- è interessante ma se 
> non
> capisco male mi costringe comunque a riscrivere tutto. Come ho 
> scritto,
> l'applicazione al momento usa intensamente SqlAlchemy, non 
> direttamente
> psycopg2. Il modulo momoko prevede che uno scriva le SQL dirette, non 
> che
> passi da un ORM. Non mi pare [1che Mike Bayer abbia progetti di
> avventurarsi in una versione asincrona di SqlAlchemy.

Per quello no, non ci puoi fare niente. Mi dispiace, ma l'idea è 
sbagliata dalll'inizio. Se il programma è asincrono/callback, NON puoi 
usare funzioni bloccanti. Non puoi farlo in twisted e non puoi farlo in 
tornado. Grazie ai wrapper asincroni puoi usare psycopg, ma perdi 
l'interfaccia dbapi, e di conseguenza tutto quello che la utilizza: 
sqlalchemy, django orm ecc. L'unico modo che io conosca di avere psycopg 
in dbapi asincrono è coi greenlet. Credo sia un disclaimer grande e 
grosso in tornado: tutto quello che blocca dev'essere in una callback: 
se non c'è sono dei criminali :-) Non è che tornado sia meglio di 
twisted da questo punto di vista.


-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


Maggiori informazioni sulla lista Python