Redis
 sql >> Database >  >> NoSQL >> Redis

Modo scalabile per registrare i dati delle richieste di pagina da un'applicazione PHP?

È certamente fattibile in una varietà di metodi. Affronterò ciascuna opzione elencata e alcuni commenti aggiuntivi.

1) Se NGinx può farlo, lascialo. Lo faccio con Apache, JBOSS e Tomcat. Quindi uso syslog-ng per raccoglierli centralmente ed elaborare da lì. Per questo percorso suggerirei un formato di messaggio di registro delimitato come separato da tabulazioni in quanto semplifica l'analisi e la lettura. Non so se registri le variabili PHP, ma può certamente registrare intestazioni e informazioni sui cookie. Se hai intenzione di utilizzare la registrazione di NGinx, consiglierei questo percorso, se possibile, perché accedere due volte?

2) Non c'è "mancanza di capacità di interrogare la data in un secondo momento", più in basso.

3) Questa è un'opzione, ma se è utile o meno dipende da quanto tempo vuoi conservare i dati e quanta pulizia vuoi scrivere. Altro sotto.

4) MongoDB potrebbe sicuramente funzionare. Dovrai scrivere le query e non sono semplici comandi SQL.

Ora, per memorizzare i dati in redis. Attualmente registro le cose con syslog-ng come indicato e utilizzo una destinazione del programma per analizzare i dati e inserirli in Redis. Nel mio caso ho diversi criteri di raggruppamento come per vhost e per cluster, quindi le mie strutture potrebbero essere leggermente diverse. La domanda che devi affrontare prima è "quali dati voglio da questi dati"? Alcuni di essi saranno contatori come le tariffe del traffico. Alcuni saranno aggregati e altri ancora saranno cose come "ordina le mie pagine in base alla popolarità".

Dimostrerò alcune delle tecniche per inserire facilmente questo in redis (e quindi tornare indietro).

Innanzitutto, consideriamo le statistiche sul traffico nel tempo. Per prima cosa decidi la granularità. Vuoi statistiche al minuto o saranno sufficienti le statistiche orarie? Ecco un modo per monitorare il traffico di un determinato URL:

Memorizza i dati in un set ordinato usando la chiave "traffic-by-url:URL:YYYY-MM-DD" in questo set ordinato utilizzerai il comando zincrby e fornirai il membro "HH:MM". ad esempio in Python dove "r' è la tua connessione redis:

r.zincrby("traffic-by-url:/foo.html:2011-05-18", "01:04",1)

Questo esempio aumenta il contatore dell'URL "/foo.html" il 18 maggio all'1:04 del mattino.

Per recuperare i dati per un giorno specifico, puoi chiamare zrange sulla chiave (""traffic-by-url:URL:YYYY-MM-DD") per ottenere un set ordinato dal meno popolare al più popolare. Per ottenere i primi 10 , ad esempio, dovresti usare zrevrange e dargli l'intervallo. Zrevrange restituisce un ordinamento inverso, il maggior numero di risultati sarà in alto. Sono disponibili diversi comandi impostati più ordinati che ti consentono di eseguire query carine come l'impaginazione, ottenere un gamma di risultati per punteggio minimo, ecc.

Puoi semplicemente modificare o estendere il nome della tua chiave per gestire diverse finestre temporali. Combinando questo con zunionstore puoi eseguire automaticamente il roll-up a periodi di tempo meno granulari. Ad esempio, potresti eseguire un'unione di tutte le chiavi in ​​una settimana o in un mese e archiviarle in una nuova chiave come "traffic-by-url:monthly:URL:YYYY-MM". Facendo quanto sopra su tutti gli URL in un determinato giorno puoi ottenere ogni giorno. Naturalmente, potresti anche avere una chiave di traffico totale giornaliera e incrementarla. Dipende principalmente da quando desideri che i dati vengano inseriti:offline tramite l'importazione di file di registro o come parte dell'esperienza utente.

Consiglierei di non fare molto durante la sessione utente effettiva poiché estende il tempo necessario agli utenti per sperimentarlo (e il carico del server). Alla fine si tratterà di una chiamata basata sui livelli di traffico e sulle risorse.

Come puoi immaginare, lo schema di archiviazione di cui sopra può essere applicato a qualsiasi statistica basata su contatore che desideri o determini. Ad esempio, cambia l'URL in ID utente e hai il monitoraggio per utente.

Puoi anche archiviare i log non elaborati in Redis. Lo faccio per alcuni registri che li memorizzano come stringhe JSON (li ho come coppie chiave-valore). Poi ho un secondo processo che li estrae e fa cose con i dati.

Per memorizzare i colpi grezzi puoi anche usare un set ordinato usando Epoch Time come classifica e afferrare facilmente una finestra temporale usando i comandi zrange/zrevrange. Oppure archiviarli in una chiave basata sull'ID utente. I set funzionerebbero per questo, così come i set ordinati.

Un'altra opzione che non ho discusso ma per alcuni dei tuoi dati potrebbe essere utile è l'archiviazione come hash. Questo potrebbe essere utile, ad esempio, per memorizzare informazioni dettagliate su una determinata sessione.

Se vuoi davvero che i dati siano in un database, prova a utilizzare la funzione Pub/Sub di Redis e chiedi a un abbonato che li analizzi in un formato delimitato e li scarichi in un file. Quindi avere un processo di importazione che utilizza il comando copy (o equivalente per il tuo DB) per importare in blocco. Il tuo DB ti ringrazierà.

Un ultimo consiglio qui (probabilmente ho già preso abbastanza tempo mentale) è di fare un uso giudizioso e liberale del comando di scadenza. Utilizzando Redis 2.2 o versioni successive è possibile impostare la scadenza sui tasti del contatore pari. Il grande vantaggio qui è la pulizia automatica dei dati. Immagina di seguire uno schema come quello che ho delineato sopra. Utilizzando i comandi di scadenza è possibile eliminare automaticamente i vecchi dati. Forse vuoi statistiche orarie per un massimo di 3 mesi, quindi solo le statistiche giornaliere; statistiche giornaliere per 6 mesi poi solo statistiche mensili. Basta far scadere le tue chiavi orarie dopo tre mesi (86400*90), le tue chiavi giornaliere alle 6 (86400*180) e non avrai bisogno di pulire.

Per il geotagging eseguo l'elaborazione offline dell'IP. Immagina un set ordinato con questa struttura chiave:"traffic-by-ip:YYYY-MM-DD" utilizzando l'IP come elemento e utilizzando il comando zincryby sopra indicato si ottengono dati sul traffico per IP. Ora, nel tuo rapporto, puoi ottenere l'insieme ordinato ed eseguire ricerche dell'IP. Per risparmiare traffico durante l'esecuzione dei rapporti, è possibile impostare un hash in redis che associa l'IP alla posizione desiderata. Ad esempio "geo:country" come chiave e IP come membro hash con codice paese come valore memorizzato.

Un grande avvertimento che vorrei aggiungere è che se il tuo livello di traffico è molto alto potresti voler eseguire due istanze di Redis (o più a seconda del traffico). La prima sarebbe l'istanza di scrittura, non avrebbe l'opzione bgsave abilitata. Se il tuo traffico è piuttosto alto, farai sempre un bgsave. Questo è ciò per cui consiglio la seconda istanza. È schiavo del primo e salva su disco. Puoi anche eseguire le tue query sullo slave per distribuire il carico.

Spero che questo ti dia alcune idee e cose da provare. Gioca con le diverse opzioni per vedere cosa funziona meglio per le tue esigenze specifiche. Sto monitorando molte statistiche su un sito Web ad alto traffico (e anche statistiche di registro MTA) in redis e funziona magnificamente - combinato con Django e l'API di visualizzazione di Google ottengo grafici molto belli.