Connect.gt

Condividiamo idee e conoscenza dal 2003...
...dopo 17 anni una Nuova Storia è nata
Scopri di più



GTStats

Collaboratori

fdalesio, Tiago, gik25, luckylinux, probid, gorka, mix

File da scaricare

Query eseguite all'arrivo di un utente

Tabella con Query divise per table e INSERT/SELECT

Progetto

Database

Progettazione del nuovo DB

Tool per l'importazione da PHPStats

Query Inserimento e aggregazione dei dati


Codice e SVN

http://www.gt-stats.org/gtstats-core/

Codice riutilizzabile

Programmazione strutturata in classi

Documentazione classi

Classe QueryWriter (nessuna query dovrà essere eseguita senza usare questa classe)

Cattura dati utente

Benchmark e ottimizzazione

Rendering grafico

Plugin

Integrazione

Con altri sistemi di statistiche tramite XML (importazione da script a xml e da xml a GTStats)


Il codice di GTStats sarà inizialmente PHP 4, strutturato in numerose classi e funzioni. Cercando di ridurre al minimo la replicazione del codice. Il codice sarà documentato. Cercheremo di sfruttare PEAR, template engine e la massima ottimizzazione possibile per un Database.

Il codice MySQL delle query sarà gestito esclusivamente all'interno della classe QueryWriter, questa classe conterrà internamente una matrice nella quale ogni cella rappresenta una query SQL. Tramite i metodi pubblici di questa classe saranno passati i parametri e le informazioni necessarie incapsulate a loro volta in un oggetto.

In pratica quando devo fare una query passo a una funzione la tabella su cui voglio operare, e la modalità (INSERT, SELECT, ecc) e i parametri. Il codice MySQL è contenuto dentro questa classe che va studiata a tavolino.


Risparmiare spazio su DB è molto importante: l'ip deve diventare un numero (si usa la funzione ip2long di PHP), dobbiamo sfruttare i tipi enum e le funzioni hash to integer come CRC32 MD5 e in generale altre Hash a 32 bit

Studiamo un sistema di statistiche preesistente

Partiamo da considerazioni su un sistema esistente, al fine di capire come migliorarlo. PHPStats è un ottimo software, ma ha dei problemi di efficienza dovuti al numero di operazioni di scrittura su database per ciascun utente.

In questo file word troverete il codice PHP che descrive le operazioni di query che PHPStats fa ad ogni accesso.

Query tracking utente

Query.doc Query tracking utente

Documentazione tabelle PHPStats


Tabella dettagli su PHPStats

visitor_id ip host agent lang date referer currentPage reso colo titlePage
varchar(50) varchar(15) varchar(50) varchar(255) varchar(10) int(10) varchar(255) varchar(255) varchar(10) varchar(10) varchar(255)

E' un id casuale di questo tipo: 9noYQgY7Ji8UkV07Sijn7GWRtKvEZy sono 30 caratteri cioè più di 931.322.574.615.478.515.625.000.000.000.000.000.00 0.000.000.000.000 utenti monitorabili. Un po' troppi, no?

Questo campo è salvato come VARCHAR(50). Per un campo fisso a 30 caratteri sarebbe meglio un CHAR(30). Ancora meglio tuttavia è sostituire tale id con un intero. Basta un bigint.

In effetti, anche un errore su un milione sarebbe più che accettabile, usare un unsigned a 32 bit (2^32 = 4 miliardi) potrebbe andare più che bene, ma si deve tenere conto di un fattore statistico noto come paradosso del giorno del compleanno. Ovvero non interessa la probabilità che un utente coincida con l'altro, ma quella che un qualsiasi utente coincida con qualsiasi altro.


In effetti quasi tutto in PHPStats è salvato come varchar, mentre il suo uso dovrebbe essere ridotto al minimo. CHAR ad esempio è preferivile se la dimensione è fissa, ma valori come l'ip possono essere salvati come numeri.

Gli user agent sono standard vanno sostituiti con un intero hard coded, se la ricerca non lo trova scrive in un file hash(id) = "$useragent". Hash perchè così ogni sistema PHPStats userà gli stessi id per i nuovi useragent.

Risoluzione deve essere un int, la conversione deve essere fatta tramite array associativo hard coded.

Colori tyniint unsigned di 4 invece che varchar(10).

"http://www." sarà sostituito con un carattere singolo magari non url safe (che quindi non potrà mai comparire in un url) accorciando referer e current page.

Il dominio sarà salvato come int e sarà hard coded in un file scritto da PHP stesso.

Lang occupa poco, comunque si potrebbe metterlo sempre come int.

Utilizzare tutto hard coded serve a ridurre al minimo il numero di query al DB.


Configurazione su db (errore)

PHPStats salva la configurazione su db. Quindi una prima query mysql serve solo a leggere la configurazione. Un include da file è in linea teorica molto più veloce visto che i db hanno requisiti di sicurezza e atomicità che li rendono più lenti. Senza considerare il caching del file in ram e il ritardo dovuto al trasferimento in rete se il DB è presente su un altro server.

Mese salvato come stringa

PHPStats salva nella tabella referer il mese come stringa.

Un numero di 10 cifre salvato come stringa occupa 10 byte, salvato come int ne occupa 2 o 4 a seconda della precisione.

Niente indici?

PHPStats non usa indici. In effetti effettua quasi solo inserimenti. Bisogna verificare con test se si tratta di una scelta ottimale.

INSERT vs INSERT DELAYED

Bisogna testare INSERT contro INSERT DELAYED e decidere quando passare da uno all'altro.

Risparmiare spazio

è un must. La velocità di una query in scrittura MySQL dipende anche dalle dimensioni, e lo spazio su database offerto dai vari hoster è spesso limitato.

Title della pagina nella tabella pages?

Come viene salvato il title della pagina nella tabella pages? Si può passare il parametro tramite js?

Documentazione

Grafici

http://www.maani.us/charts/index.php?menu=Gallery&submenu=3D_Pie


Cronjob

PHP stats fa dei controlli prima di ogni scrittura, del tipo: se le righe sono 1000 cancellane una. Lo svuotamento se frequente dovrebbe essere fatto con truncate. L'ottimizzazione va fatta di notte, e solo se ci sono cancellazioni, altrimenti è inutile.

In pratica per fare una query ne va ad eseguire cinque.


Controllare il funzionamento dei simil cronjob casuali, ogni tot utente uno scatena il controllo o meglio ogni utente ha la probabilità 1/tot di scatenare il controllo.


  • Questa pagina è stata modificata per l'ultima volta il 22 giu 2007 alle 22:10.
  • Questa pagina è stata letta 143 159 volte.