DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   PHP (http://www.devprotalk.com/forumdisplay.php?f=9)
-   -   paralelni download (http://www.devprotalk.com/showthread.php?t=2300)

ivanhoe 21. 01. 2007. 22:42

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...

Petar Marić 21. 01. 2007. 23:56

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 :)

ivanhoe 22. 01. 2007. 03:55

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...

Petar Marić 22. 01. 2007. 06:52

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 :D

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


ivanhoe 22. 01. 2007. 12:36

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 :)

Petar Marić 22. 01. 2007. 13:22

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 :)

ivanhoe 22. 01. 2007. 16:24

tja, sad cu da vidim sa klijentom koliko para je on spreman da plati, pa cemo u zavvisnosti od toga da komplikujemo algoritam :)

Thanx na ideji u svakom slucaju..

dinke 22. 01. 2007. 17:18

E, tek sad vieh ovu temu :)

Lepo ti je rekao Petar, mozes da furas non-blocking sockete, ili pcntl f-je. Ja sam svojevremeno pravio overture multisocket parser, i to radi, ali ne bas savrseno, jer je PHP "CPU intensive" jezik, pa socketi posle odredjenog vremena pocnu da pucaju samo tako.

Moj savet, drzi se perla, ili mozda da probas sa pcntl-om, a mozda cak i sa curl-om, posto u verziji php5 moze da se radi sa mutliple konekcijama(nisam probao ali cini mi se da je pomenuto u manualu).

zextra 22. 01. 2007. 21:17

Drzi se perla. :D

POE all the way.

ivanhoe 05. 02. 2007. 07:53

kako smanjiti opterecenje CPU?
 
odlucio sam da se malo igram sa curl multi funkcijama, i nasao sam jedan primer upotrebe na php.net, i po svemu sudeci to je jedini primer koji postoji o tome. :1027:

Elem tamo pise nesto ovako:
PHP kôd:

while ($active and $mrc == CURLM_OK) ) {
    
// wait for network
    
if (curl_multi_select($mh) != -1) {
        
// pull in any new data, or at least handle timeouts
        
do {
             
$mrc curl_multi_exec($mh$active);
        } while (
$mrc == CURLM_CALL_MULTI_PERFORM);
    } 
//end_if


Ova petlja u stvari radi neblokirajuci select na otvorenim socketima, samo je to sve upakovano u curl.

Ono sto mene zanima je da li ova petlja, ovako kako je napisana, nepotrebno opterecuje CPU? Da li bi bilo pametnije dodati neki mali usleep() na kraj petlje, da bi se smanjio broj pristupa socketima, u ono vreme kad na njima nema nicega za citanje. Ili bi to mozda imalo suprotan efekat, i usporilo rad, bez smanjenja server load-a ?

Jel ima neko nekog iskustva sa ovim?


Vreme je GMT +2. Trenutno vreme je 10:54.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.