konto usunięte

Temat: Propozycja wydajnego rozwiązania

Piotr Baranowski:
GA daje wyniki na pewno bardziej rzetelne - ale odpadaja ludzie
ktorzy maja wylaczony JS (znikomy odsetek ludzi tak naprawde).

Rzetelne? Mam rozumieć, że ilość odsłon mojego skryptu (jako liczba) będzie bardziej wiarygodna i prawdziwa w GL niż w logach? Dlaczego? Nie powinno być odwrotnie? Wydawało mi się, że to właśnie logi systemowe serwera zliczają ten "prawdziwy" ruch.
Piotr Baranowski

Piotr Baranowski Rozwiązuje problemy,
poprawiam świat,
chłonę wiedzę i
prz...

Temat: Propozycja wydajnego rozwiązania

Piotr Parzentny:
Piotr Baranowski:
GA daje wyniki na pewno bardziej rzetelne - ale odpadaja ludzie
ktorzy maja wylaczony JS (znikomy odsetek ludzi tak naprawde).

Rzetelne? Mam rozumieć, że ilość odsłon mojego skryptu (jako liczba) będzie bardziej wiarygodna i prawdziwa w GL niż w logach? Dlaczego? Nie powinno być odwrotnie? Wydawało mi się, że to właśnie logi systemowe serwera zliczają ten "prawdziwy" ruch.

Jezeli wezmiesz tylko pod uwage liczbe odslon skryptu - to owszem, logi maja o tym pelna informacje.
Bo tam jedna linijka == jedno wywolanie skryptu.

Ale GA na pewno lepiej pokazuje liczbe UU - bo uzywa do tego cookies, javascript'u i pewnie paru innych bajerow. W logach UU to jest po prostu IP.

Na pewno lepiej pokazuje tez liczbe odwiedzin roznych uzytkownikow - czyli ile razy ktos zaczal sesje na stronie (czyli ile razy lacznie dani UU weszli na strone).

Na pewno lepiej liczy czas lacznych odwiedzin i srednia dlugosc wizyty usera na stronie.

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Teraz mam jeszcze jaśniejszą sytuację :)
Piotr Baranowski:
Jezeli wezmiesz tylko pod uwage liczbe odslon skryptu - to
owszem, logi maja o tym pelna informacje. Bo tam jedna linijka
== jedno wywolanie skryptu.

Z tego wynika, że przy 1.000 serwisów jeśli na każdym będę miał 10.000 odsłon mojego skryptu to dostanę:

1.000 x 10.000 = 10.000.000 linijek kodu dla wcale nie wyśrubowanych danych wejściowych!

Czy przypadkiem parsowanie i zabawa takim plikiem nie potrwa za
długo i/lub nie zajedzie serwera?

EDIT:
Wyszperałem w internecie taki fragment:
"Niestety czas analizy pliku log jest znacznie dłuższy niż w przypadku programów Webalizer, Geolizer czy Analog. Analiza 600000 linii pliku log (około 60 MB) trwa ponad półtorej godziny na komputerze, na którym Webalizer analizuje 130000 rekordów na sekundę!"

Z tego wynika, że AWStats odpada...Piotr Parzentny edytował(a) ten post dnia 26.10.09 o godzinie 02:18
Michał Płonka

Michał Płonka Programista PHP

Temat: Propozycja wydajnego rozwiązania

Piotr Parzentny:
widget, który pokazywać będzie powiedzmy zdjęcie mojej twarzy ;)

:) hehe

Ale wracając do tematu. Może wróć do swego pierwotnego planu czyli tabeli (w skrócie):

- tabela 1 z polami: WEBSITE_ID, COUNTER,
- tabela 2 z polami: WEBSITE_ID, IP, TIME.

Za każdym razem, gdy uruchamia się widget dodajesz rekord do drugiej tabeli dla danej strony. Nie robisz nic więcej - zwykły INSERT. Równocześnie masz utworzone zadanie CRONa (lub nawet na poziomie bazy danych np. event dla MySQL), które co jakiś czas (np. w późnych godzinach nocnych) aktualizuje Ci statystyki na podstawie odwiedzin. Sprowadzi się to do wykonania jednego zapytania UPDATE z wykorzystaniem COUNT dla poszczególnych WEBSITE_ID.

Taki mechanizm wydaje mi się najefektowniejszy.

Jeżeli korzystałbyś z MySQL (a pewnie tak będzie) to rozważ jeszcze te kwestie:
1. Tabela 2 mogłaby być typu MyISAM. Przyspieszyłoby to wprowadzanie nowych rekordów.
2. Wprowadzanie nowych rekordów warto by było wykonywać z flagą DELAYED dla INSERT; nie jest przecież istotne czy rekord pojawi się natychmiast, czy odrobinę później.
3. Rozważyłbym wywalenie jakichkolwiek indeksów z tabeli 2. Dopiero w momencie aktualizacji statystyk możnaby założyć odpowiednie indeksy, a po ich wykonaniu z powrotem je usunąć. Nie wiem w jakim stopniu wpłynie to na wydajność (czy dodawanie indeksu nie będzie bardziej kosztowne niż jego aktualizacja przy każdorazowym INSERcie), ale warto by było spróbować.
4. Zakładam, że adres IP będziesz trzymał w postaci stringa - może lepiej byłoby mieć go w postaci BIGINT?

To chyba tyle z moich koncepcji.

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Michał Płonka:
Za każdym razem, gdy uruchamia się widget dodajesz rekord do drugiej tabeli dla danej strony. Nie robisz nic więcej - zwykły
INSERT.

Dla 1.000 serwisów o średniej ilości odsłon 50.000 (dane w końcu całkiem realne) wychodzi 19,3 INSERTów na sekundę. Baza musiałaby nawet z flagą DELAYED pracować prawie cały czas! Czy podoła? Poza tym tak jak wspomniano wcześniej tą metodą uzyskam jedynie ilość wyświetleń widgeta. Mierzenie chociażby UU jest tutaj utrudnione.
To chyba tyle z moich koncepcji.

Dzięki za rady. Jest kolejny temat do przemyśleń.

Pozdrawiam.
Robert B.

Robert B. Web Development
Manager

Temat: Propozycja wydajnego rozwiązania

Jeśli działanie w trybie rzeczywistym (na bieżąco obserwacja ruchu) nie stanowi problemu, a rozumiem, że nie stanowi, to proponuję takie rozwiązanie:

1. Ciasteczko, sprawdzane na poziomie serwera WWW (htaccess lub najlepiej w konfiguracji vhosta - bo działa to szybciej). Tzn.: jeśli ciasto istnieje to nawet nie odpalaj skryptu PHP.

2. Albo zapisujemy cały ruch - czyli logi serwera WWW w bazie danych - można je łatwo rozdzielić pomiędzy wiele tabel/baz danych (ręcznie, lub za pomocą partycji).
Albo w czasie rzeczywistym sprawdzamy czy można zrobić update (zwiększyć licznik odwiedzin stron) - polecam procedury i/lub triggery, żeby cała logika była w bazie danych. W drugim przypadku oczywiście podział na osobne tabele/bazy danych też jest dobrym pomysłem.

3. Statystyki podliczamy na żądanie - czyli jak ktoś otworzy panel do przeglądania wyników to uruchamiany jest automat.

Logikę trzymał bym w bazie danych, więc język jest drugorzędny - cokolwiek co potrafi połączyć się z bazą danych i uruchomić procedurkę.

Generalnie: podzielił bym dane na wiele tabel.
Michał Płonka

Michał Płonka Programista PHP

Temat: Propozycja wydajnego rozwiązania

Piotr Parzentny:
Dla 1.000 serwisów o średniej ilości odsłon 50.000 (dane w końcu całkiem realne) wychodzi 19,3 INSERTów na sekundę. Baza musiałaby nawet z flagą DELAYED pracować prawie cały czas! Czy podoła?
Cytując z booka, którego ostatnio Ci podałem:
MySQL can run more than 50,000 simple queries per second on commodity server hardware and over 2,000 queries per second from a single correspondent on a Gigabit network.

Tak więc wydaje się, że niespełna 20 zapytań na sekundę to pryszcz :)

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Teraz to już naprawdę mam nad czym pomyśleć ;) Wybór dalej jest ciężki, a muszę dokonać go na początku tworzenia projektu. Tak czy inaczej wielkie dzięki wszystkim!
Michał Płonka

Michał Płonka Programista PHP

Temat: Propozycja wydajnego rozwiązania

Ja bym poważnie rozważył zastosowanie PostgreSQL w miejsce MySQL. Przy sporej (wiem, pojęcie względne) liczbie rekordów MySQL potrafi ponoć nieźle przymulić. Na tym polu PostgreSQL jest bardziej skalowalny i nie ma aż takch drastycznych spadków wydajności. Na szczęście stosując mechanizm abstrakcji bazy danych będziesz mógł w prosty sposób w przyszłości zmienić silnik bazy na inny.

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Tylko że access logi i tak mam na serwerze, a rozwiązanie z bazą
wymaga dodatkowych operacji, a co za tym idzie zwiększa koszt całej zabawy. Wydaje mi się, że zużyję wtedy więcej transferu. Chyba, że coś źle rozumuje. Po namyśle zastanawiam się jednak nad hybrydą logów i GA.

Pytanie tylko czy dałoby się to jakoś bardziej elegancko zrobić
z GA niż wykorzystanie iframe? Jest taka technika wogóle zgodna z ich regulaminami?Piotr Parzentny edytował(a) ten post dnia 26.10.09 o godzinie 21:09

konto usunięte

Temat: Propozycja wydajnego rozwiązania

To może jeszcze spytam inaczej. Jak w takim razie może działać i być zorganizowany serwis typu: http://www.statystyki-stron.pl/ ?
Tomasz B.

Tomasz B. Senior Software
Engineer

Temat: Propozycja wydajnego rozwiązania

Witam kolegę.
Troszkę wiem w czym tak naprawdę widzisz problem, po pierwsze nawet jak będziesz miał jeśli będziesz miał wyświetleń swojego skryptu 1 milion dziennie to pamiętaj że w tym samym momencie tak naprawdę maksymalnie będzie wywoływało twój skrypt max. około kilka tys.
Na moich serwerach access logi są robione codzie i automatycznie pakowane do gzip (w nocy małe obciążenie) (log-27-10-2009.gz).
Pobierasz taki log ftp na swoją masznę lub inną (lub robisz operację w nocy) Zapodajesz parser loga dziennego idziesz na piwo :) po 4 godzinach wracasz z piwa i masz wyniki gotowe. Wrzucasz sobie wyniki do DB.
Wszystko to można zautomatyzować na serwerze więc tylko zostaje tobie piwko do picia i oglądanie gotowych wyników.
Moja rada "idź dalej po złote runo nicości" - Z.H., szkoda czasu, sprawdzisz po testujesz, wybierzesz najlepszą metodę.

konto usunięte

Temat: Propozycja wydajnego rozwiązania

w tym samym momencie tak naprawdę maksymalnie będzie wywoływało twój skrypt max. około kilka tys.

I to nie zarżnie mi serwera? :) Od czego ilość jednoczesnych wywołań skryptu jednocześnie może zależeć? Rozumiem, że od serwera, ale jaki mam na to wpływ?
Zapodajesz parser loga dziennego idziesz na piwo :) po 4
godzinach wracasz z piwa i masz wyniki gotowe. Wrzucasz
sobie wyniki do DB. Wszystko to można zautomatyzować na serwerze więc tylko zostaje tobie piwko do picia i oglądanie gotowych wyników.

Nie piję piwa ;) Poza tym z tego co wycztałem to te parsery napisane w C obrabiają 2mln linijek w 30 sekund. Więc tutaj nie 4h tylko 15sek :) Te rozwiązanie jednak bardzo mi się podoba. Gorzej z analizą sparsowanych danych. To już może trwać...

Dzięki za rady.Piotr Parzentny edytował(a) ten post dnia 27.10.09 o godzinie 23:17
Wojciech K.

Wojciech K. realizator pomysłów
własnych

Temat: Propozycja wydajnego rozwiązania

Piotr Parzentny:
że określone IP nie wystąpiło w ostatniej godzinie (pole TIME).

1
żeby nie sprawdzać niepotrzebnie w zapytaniu warunkiem tego TIME, możesz oddzielnym skryptem np. raz na minutę kasować wszelkie wpisy w tabeli nr 2 starsze niż godzina - wtedy skracasz zapytanie o jeden warunek

2
IP zapisujesz jako int (ip2long) a nie jako varchar ("123.123.123.123")

3
taką tabelę - skoro to jest typowa "tymczasówka" warto trzymać w pamięci, a nie w pliku.
Daniel Częstki

Daniel Częstki senior php developer

Temat: Propozycja wydajnego rozwiązania

nie wiem czy bylo, ale ja bym umiescil w sesji jakis znacznik czasu

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Może już podjąłeś decyzje i teraz trochę zamieszam, ale istnieje lepsze rozwiązanie niż MySQL, czy PostgreSQL lub pliki z logami. Gdy w grę wchodzi zapis dużej ilości prostych danych z pomocą może przyjść MongoDB - prosta instalacja, proste użycie, szybki zapis, może być użyta jako cache .... Tutaj artykuł z pewnego wdrożenia, który może pomóc w podjęciu decyzji: http://blog.boxedice.com/2009/07/25/choosing-a-non-rel...

Pozdrawiam.

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Piotr Ł.:
Może już podjąłeś decyzje i teraz trochę zamieszam, ale istnieje lepsze rozwiązanie niż MySQL, czy PostgreSQL lub pliki z logami. Gdy w grę wchodzi zapis dużej ilości prostych danych z pomocą może przyjść MongoDB - prosta instalacja, proste użycie, szybki zapis, może być użyta jako cache .... Tutaj artykuł z pewnego wdrożenia, który może pomóc w podjęciu decyzji: http://blog.boxedice.com/2009/07/25/choosing-a-non-rel...

Pozdrawiam.
żeby instalować własne dodatki (nosql) trzeba mieć serwer dedykowany. żeby mieć sql wystarczy VPS. jest różnica? więc nie zawsze można.
Bartłomiej Ogryczak

Bartłomiej Ogryczak Backend Developer @
Layar

Temat: Propozycja wydajnego rozwiązania

Tomasz B.:
Hej najlepiej rozdzielać takie obciążenie na poziomie serwerowym najbardziej wydajne. Jak to działa to tak na szybko http://linux.gda.pl/spotkania/sp_24/klastry.pdf .

Chcesz powiedzieć, że widziałeś *w praktyce* dobrze działającą replikację Master-Master na MySQL? Nie mówiąc już o tym, że to niewiele daje, bo każdy master i tak będzie musiał wykonać wszystkie inserty.
Karol Nowacki

Karol Nowacki Programista PHP,
Perl, C,
administrator
systemów *NIX

Temat: Propozycja wydajnego rozwiązania

a może tak: napisać malutki proxy do bazy z tymi zapytaniami np w perlu, które działało by jako daemon w tle. Baza dany zawierała by jedynie tabelkę pierwszą tj, (WEBSIDEID, COUNTER), natomiast wyłapywanie duplikatów odbywało by się na poziomie tego proxy.

Skrypt w php, zamiast pchać zapytanie do bazy pisał by np. na pipkę/gniazdko do tego proxy coś linijkę typu WEBSIDE_ID, IP, ip może już być typu int a nie ciąg znaków. Proxy trzyma sobie cały czas w pamięci tablicę indexowaną WEBSIDEID, a jej elementami są drzewa BST, których liście są konstrukcji array(ip, time). Sprawdza czy na drzewie danego WEBSIDEID jest dane ip, jak jest to aktualizuje czas, a jak nie ma to dodaje na drzewo i wysyła zapytanie (raz spreparowane) do bazy o aktualizację danego rekordu w tablicy. Dodatkowo co jakiś czas (np co minutę) wywoływana jest subrutynka, która robi porządek na drzewku i wyrzuca przestarzałe wpisy.

Opcja dwa jak ktoś nie chce pisać proxy można wykorzystać np. Memcache jako to co trzyma IPiki które nas odwiedziły. Jako klucz przyjmując np. ip:WEBSIDEID:myhash(ip) , gdzie myhash ip będzie jakimś szybkim skrótem ip do 2 znaków i pod takim kluczem trzymamy tablicę ipków wraz z czasem które pasują do tego klucza. Expire dla MC to największy time z rekordów w tablicy + godzin. To rozwiązanie zwala dużo więcej roboty na maszynę interpretująca PHP a odciąża bazę danych. Jak ktoś ma farmę kilkunastu (kilkudziesięciu ;)) indian i jedną/dwie bazy danych ma to sens. Bo dużo łatwiej jest zrównoleglić webserwerki niż bazę.

A jak ktoś ma jeszcze większy wymagania, to pisze sobie takie proxy w C na drzewach AVL robi 7 maszynek na którym to stawia i zapytanie o aktualizację wpisu wysyła na iptestmachine(IP % 7), które to odpytują Oracla... ale jak ktoś ma takie problemy, to nie pyta o nie na forum ;)

konto usunięte

Temat: Propozycja wydajnego rozwiązania

Piotr P.:
Stanisław Pitucha:
To czemu chcesz to robić po raz drugi w skrypcie, jeśli prawdopodobnie masz wszystkie dane jakie potrzebujesz w logach
serwera? (ip, czas, url)

O tym nie pomyślałem! Dalej jednak interesuje mnie kwestia różnic językowych. Czy zabawa z takimi logami będzie dużo bardziej wydajna w innych językach niż PHP? Znacie może też jakieś klasy do obsługi logów? Żebym przypadkiem na nowo koła nie wymyślał :)

Tylko się zastanawiam po co to ma być wydajne?
Przecież skanowanie logów i tak robisz w tle, więc może to chodzić nawet i tydzień... (przy pierwszym uruchomieniu).

PHP jest wystarczający do tego celu. Sam skanowałem w nim logi z zakresu roku.
Oczywiście Off-line.

Skanowanie możesz robić codziennie, wtedy PHP się spokojnie wyrobi.



Wyślij zaproszenie do