[Python] Python, redis e bottleneck

Roberto De Ioris roberto a unbit.it
Gio 19 Dic 2013 14:06:59 CET


> Il giorno gio, 19/12/2013 alle 13.07 +0100, Roberto De Ioris ha scritto:
>> >>
>> >> 2013/12/19 Pietro Battiston <me a pietrobattiston.it>
>> >
>> >
>> >> [...]
>> >>
>> >> Io credo che ci possa essere relazione a come e' scritto il codice.
>> >
>> >
>> > OK, ragionevole dubbio. Prendi _questo_ codice:
>> >
>> > import redis
>> > import random
>> >
>> > r = redis.Redis(db=0)
>> >
>> > try:
>> >     while True:
>> >         r[random.random()] = random.random()
>> > except KeyboardInterrupt:
>> >     r.flushdb()
>> >
>> >
>> > che gira su un vecchio Intel Core2 Duo CPU T7300, a 2 GHz, con 4 GB di
>> > RAM DDR2 a 667 MHz.
>>
>>
>>
>> > - Cosa posso immaginare che stia succedendo: che ci sia una latenza
>> tra
>> > CPU e cache, o tra una CPU e l'altra CPU, o tra le CPU e la RAM, che
>> > "top" non sia affidabile al 100%.
>>
>>
>> no no fermo, i risultati che hai sono in linea con il tuo approccio, il
>> collo di bottiglia e' il tuo hardware nel suo insieme :)
>>
>
> Wow. Confesso che la tua mail mi ha suggerito che forse la seguente riga
> di "top":
>
> %Cpu(s): 41,5 us, 13,2 sy,  0,0 ni, 44,8 id,  0,2 wa,  0,0 hi,  0,4 si,
> 0,0 st
>
> non fosse lì per bellezza.
>
> A questo punto mi resta un dubbio: "sy" dovrebbe in effetti
> rappresentare per l'appunto il tempo speso in kernel space. Considerato
> che i valori sopra sommano a 100, il tempo speso nel context switching
> in sé sarà incluso in questo valore? In "id"? Spalmato tra "sy" e
> "us" (a seconda della "direzione" del context switching)? Tutto sommato
> irrilevante?


per context switch in realta' si intende il tempo (software) impiegato dal
sistema a tornare in "kernel mode" (e viceversa) diciamo che e' solo una
piccola parte di 'sy' (che comprende anche il tempo impiegato dalla
syscall stessa) ma ha comunque il suo peso nell'insieme.

Se ti interessa (presumo di si) leggiti le vecchie (ora e' cambiato
parecchio ed e' imho piu' complesso da capire) guide su come chiamare una
syscall in assembler x86 (int 0x80). Questi frammenti di codice (sperando
che siano commentati) di solito chiariscono le idee molto piu' di interi
libri di teoria sui sistemi operativi.

>
>
>> >
>> > - Cosa me ne frega: pura curiosità, e magari pure un indizio di quanto
>> > parallelizzare codice che utilizza in modo intensivo redis possa o
>> meno
>> > migliorare le prestazioni in modo lineare, o se viceversa qualunque
>> cosa
>> > mi stia facendo da bottleneck adesso si riproporrebbe anche
>> > parallelizzando, magari su più di 2 CPU.
>> >
>>
>>
>> redis e' mono thread, puoi 'parallelizzare' la parte python ma visto che
>> l'hardware ha "solo" 2 cpu e hai comunque 2 processi fissi
>> nell'equazione
>> (python e redis) non otterresti alcun vantaggio (anzi peggioreresti)
>>
>
>
> Sento che sto per vedere la luce, ma non mi è ancora chiarissimo perché
> un processo python aggiuntivo, magari con niceness bassa, non potrebbe
> sfruttare il 60% di CPU che il processo redis non utilizza - anche
> eventualmente "sprecandone" un 10% in kernel space, e quindi girando al
> 50%...
>

perche' andrebbe a pesare su redis nuovamente, di fatto introducendo
un'altra problematica, ovvero che redis deve gestire due stream di
richieste diventando il vero collo di bottiglia.

Ovviamente se cambi l'architettura in modo che uno solo legga e tutti e
due processano il discorso cambia, ma non so quanto sia fattibile nel tuo
caso.


-- 
Roberto De Ioris
http://unbit.it


Maggiori informazioni sulla lista Python