|
21. 01. 2007. | #1 |
Ivan Dilber
Sir Write-a-Lot
|
paralelni download
treba da napravim php skriptu koja skuplja neke podatke sa neta, i zbog perfomansi to treba da se radi u paraleli, znaci da se otvore sve konekcije, saceka malo i pogleda sta je skinuto, a ne klasicna skini jedno, skini drugo, skini trece sekvenca...naravno postojace kesiranje skinutih podataka, ali ocekivani cache hit rate je vrlo nizak tako da cu morati da obratim paznju na perfomanse, da se to sve ne bi vuklo najstrasnije..
Imam dve ideje, jedna je da probam da otvorim vise socketa i da onda koristim non-blocking select da ih citam u paraleli kako stizu podaci, ili druga varijanta da pomocu exec pokrenem nekoliko instanci wgeta (svaku u zasebnom shellu) koje bi skidale rezultate u fajl, i onda na kraju preparsiram te fajlove. Prvu varijantu sam vec radio u perlu, ali nemam pojma kako to radi u php-u, jel ima neko iskustva sa tim ? Dinke ? Nemam pojma koja varijanta je bolja u smislu perfomansi (pre svega me zanima server load vs. brzina), sta mislite ?? Jel imate mozda neku bolju ideju ? Da li postoji neka varijanta da se forkuju procesi u php-u pod apachom ? to bi isto mogao da bude alternativni pristup, mada sumnjam da bi to imalo bolje perfomanse...
__________________
Leadership is the art of getting people to want to do what you know must be done. |
22. 01. 2007. | #2 |
Python Ambassador
Master
|
Moj savet je da ako si ograničen na PHP radiš preko neblokirajućih socketa i da onda postaviš sinhronizacionu barijeru kada se svi završe i potom pređeš na drugi ciklus obrade, pa opet na barijeru - i tako dok ne završiš sve.
Problem je što će ti to biti mnogo sporije nego kad imaš niti jer kada jedna nit završi jedan UnitOfWork može odmah da počne sledeći dok ti sa barijerom moraš da sačekaš da svi završe da bi počeo novi ciklus obrade. Sad zamisli da su svi zahtevi OK (cca 2-3 sec) a da je jedan timeout (ie 90 sec) - što imaš veći broj "niti" efikasnost ti opada. Ono što ti definitvno ne preporučujem je forkovanje procesa ako ti PHP radi pod Apache-om, i ovako je dovoljno komplikovano jer je AFAIK threadsafe misaona imenica za PHP. Mada je uvek bolje sa nitima nego njenim simulacijama - ako nisi ograničen samo na PHP - pogledaj s leve strane ovoga unosa za preporku platforme
__________________
Python Ambassador of Serbia |
22. 01. 2007. | #3 |
Ivan Dilber
Sir Write-a-Lot
|
ma nisam ja za pitona , ja bih koristio perl za takve stvari, ali za sada se drzim ideje o php-u...
sto se tice ovoga sto pominjes sa kasnjenjem, to se lako resi sa timeoutom: ako nisu stigli podaci cancelujem taj request i krenem iz pocetka novi krug... za neblokirajuce sockete to nije problem uraditi...
__________________
Leadership is the art of getting people to want to do what you know must be done. |
22. 01. 2007. | #4 |
Python Ambassador
Master
|
Dinke je u jednoj ranijoj temi spominjao interesantan članak koji ti može pomoći kod asinhronih zahteva.
Što se tiče problema sa kašnjenjem izgleda da sam pogrešio - prikačio sam uz poruku programče koje pokazuje da sa povećanjem konekcija po ciklusu efikasnost raste. Program simulira rad sa socketima u asinhronom i sekvencijalnom režimu koristeći se izvesnim matematičim aproksimacijama i prikazuje koliko je puta asinhroni režim brži od sekvencijalnog - dobijeni rezultati su veoma interesantni. Nemojte se iznenaditi time što je kod u Python-u Kôd:
""" Skripta za poredjenje brzine izmedju asinhronog i normalnog (sekvencijalnog) pristupa socketima """ __author__ = 'Petar Maric - http://www.petarmaric.com/' UKUPNO_KONEKCIJA = 1000 KONEKCIJA_PO_CIKLUSU = 20 MIN_TRAJANJE = 1 MAX_TRAJANJE = 25 TIMEOUT_KONEKCIJE = 15 ########################################### # Ne bi valjalo da cackate ispod ove linije ########################################### import random DUZINE_TRAJANJA_KONEKCIJA = [ random.uniform(MIN_TRAJANJE, MAX_TRAJANJE) for i in xrange(0, UKUPNO_KONEKCIJA) ] BROJ_CIKLUSA = int(UKUPNO_KONEKCIJA/KONEKCIJA_PO_CIKLUSU) + (UKUPNO_KONEKCIJA%KONEKCIJA_PO_CIKLUSU > 0) def stvarno_trajanje(trajanje): return min(trajanje, TIMEOUT_KONEKCIJE) def trajanje_sekvencijalnih_zahteva(): return sum( map(stvarno_trajanje, DUZINE_TRAJANJA_KONEKCIJA) ) def trajanje_asinhronih_zahteva(): return sum( [ max( map(stvarno_trajanje, DUZINE_TRAJANJA_KONEKCIJA[ciklus*KONEKCIJA_PO_CIKLUSU:(ciklus+1)*KONEKCIJA_PO_CIKLUSU]) ) for ciklus in xrange(0, BROJ_CIKLUSA) ] ) efikasnost = trajanje_sekvencijalnih_zahteva() / trajanje_asinhronih_zahteva() print "Asinhroni socketi su efikasniji od sekvencijalnih %.2f puta" % efikasnost
__________________
Python Ambassador of Serbia |
22. 01. 2007. | #5 |
Ivan Dilber
Sir Write-a-Lot
|
zanimljivo programce, jedino nisam siguran da je raspored kasnjenja opisan uniformnom raspodelom, pre bih rekao da je to neka poasonova ili mozda gausova raspodela... nemam pojma da li to utice na krajnji zakljucak, doduse...
Uzgred ovaj link je bas ono sto mi treba, thanx
__________________
Leadership is the art of getting people to want to do what you know must be done. Poslednja izmena od ivanhoe : 22. 01. 2007. u 13:43. |
22. 01. 2007. | #6 |
Python Ambassador
Master
|
Uniformnu raspodelu sam uzeo zato što mi se to čini kao najgori slučaj - želeo sam da dam pesimističku sliku minimalnog ubrzanja.
Nije nikakav problem da ubaciš drugu raspodelu, ili čak da ga nahraniš živim podacima - ovo je bio samo proof-of-concept. Hehe, upravo sam dobio perverziju od ideje ako ti je rešenje sa asinhronim zahtevima presporo: algoritam u zavisnosti od dosadašnjih rezultata i parametara predviđa optimalnu dužinu ciklusa pred početak narednog
__________________
Python Ambassador of Serbia |
|
|
Slične teme | ||||
Tema | Početna poruka teme | Forum | Odgovori | Poslednja poruka |
Download day | cvele | Opušteno | 0 | 29. 05. 2008. 11:51 |
download counter | ivanhoe | (X)HTML, JavaScript, DHTML, XML, CSS | 2 | 10. 08. 2006. 07:19 |
Download skripta | Bojan Zivanovic | PHP | 8 | 18. 01. 2006. 00:21 |