Het is zeker uitvoerbaar op verschillende manieren. Ik zal elke vermelde optie behandelen, evenals wat aanvullend commentaar.
1) Als NGinx het kan, laat het dan. Ik doe het zowel met Apache als met JBOSS en Tomcat. Ik gebruik dan syslog-ng om ze centraal te verzamelen en van daaruit te verwerken. Voor deze route zou ik een gescheiden indeling voor logberichten voorstellen, zoals tab-gescheiden, omdat dit het ontleden en lezen gemakkelijker maakt. Ik weet niet of het PHP-variabelen logt, maar het kan zeker headers en cookie-informatie loggen. Als je NGinx-logboekregistratie gaat gebruiken, zou ik deze route indien mogelijk aanbevelen - waarom twee keer inloggen?
2) Er is geen "gebrek aan mogelijkheid om de datum op een later tijdstip op te vragen", meer hieronder.
3) Dit is een optie, maar of het nuttig is, hangt af van hoe lang u de gegevens wilt bewaren en hoeveel opschoning u wilt schrijven. Hieronder meer.
4) MongoDB zou zeker kunnen werken. Je zult de queries moeten schrijven en het zijn geen simpele SQL-commando's.
Nu, om de gegevens in redis op te slaan. Ik log momenteel dingen met syslog-ng zoals vermeld en gebruik een programmabestemming om de gegevens te ontleden en in Redis te stoppen. In mijn geval heb ik verschillende groeperingscriteria, zoals per vhost en per cluster, dus mijn structuren kunnen een beetje anders zijn. De vraag die u eerst moet beantwoorden, is "welke gegevens wil ik uit deze gegevens halen"? Sommige daarvan zullen tellers zijn, zoals verkeerstarieven. Een deel hiervan zullen aggregaten zijn, en nog meer zullen dingen zijn als "mijn pagina's rangschikken op populariteit".
Ik zal enkele technieken demonstreren om dit gemakkelijk in redis (en dus weer terug) te krijgen.
Laten we eerst eens kijken naar de statistieken van het verkeer in de loop van de tijd. Bepaal eerst de granulariteit. Wil je statistieken per minuut of zijn statistieken per uur voldoende? Hier is een manier om het verkeer van een bepaalde URL te volgen:
Sla de gegevens op in een gesorteerde set met de sleutel "traffic-by-url:URL:YYYY-MM-DD" in deze gesorteerde set gebruik je het zinrby-commando en geef je het lid "HH:MM" op. bijvoorbeeld in Python waar "r' uw redis-verbinding is:
r.zincrby("traffic-by-url:/foo.html:2011-05-18", "01:04",1)
Dit voorbeeld verhoogt de teller voor de url "/foo.html" op 18 mei om 1:04 in de ochtend.
Om gegevens voor een specifieke dag op te halen, kunt u zrange aanroepen op de toets (""traffic-by-url:URL:YYYY-MM-DD") om een gesorteerde set te krijgen van minst populair naar meest populair. Om de top 10 te krijgen , u zou bijvoorbeeld zrevrange gebruiken en het het bereik geven. Zrevrange retourneert een omgekeerde sortering, de meeste hit staat bovenaan. Er zijn verschillende meer gesorteerde set-opdrachten beschikbaar waarmee u leuke zoekopdrachten kunt uitvoeren, zoals paginering, een bereik van resultaten op basis van minimumscore, enz.
U kunt uw sleutelnaam eenvoudig wijzigen of uitbreiden om verschillende tijdelijke vensters aan te kunnen. Door dit te combineren met zunionstore kun je automatisch doorrollen naar minder gedetailleerde tijdsperioden. U kunt bijvoorbeeld alle sleutels in een week of maand samenvoegen en in een nieuwe sleutel opslaan, zoals "traffic-by-url:monthly:URL:YYYY-MM". Door het bovenstaande te doen op alle URL's die je op een bepaalde dag kunt krijgen. Natuurlijk kunt u ook een dagelijkse totale verkeerssleutel hebben en die verhogen. Het hangt meestal af van wanneer u wilt dat de gegevens worden ingevoerd - offline via het importeren van logbestanden of als onderdeel van de gebruikerservaring.
Ik raad af om veel te doen tijdens de daadwerkelijke gebruikerssessie, omdat het de tijd verlengt die uw gebruikers nodig hebben om het te ervaren (en serverbelasting). Uiteindelijk zal dat een oproep zijn op basis van verkeersniveaus en bronnen.
Zoals je je kunt voorstellen, kan het bovenstaande opslagschema worden toegepast op elke op een teller gebaseerde statistiek die je wilt of bepaalt. Verander bijvoorbeeld de URL in gebruikers-ID en je hebt tracking per gebruiker.
U kunt logbestanden ook onbewerkt opslaan in Redis. Ik doe dit voor sommige logboeken die ze opslaan als JSON-tekenreeksen (ik heb ze als sleutel-waardeparen). Dan heb ik een tweede proces dat ze eruit haalt en dingen doet met de gegevens.
Voor het opslaan van onbewerkte hits kunt u ook een gesorteerde set gebruiken met de Epoch Time als rangorde en gemakkelijk een tijdelijk venster pakken met de zrange/zrevrange-commando's. Of sla ze op in een sleutel die is gebaseerd op de gebruikers-ID. Sets zouden hiervoor werken, net als gesorteerde sets.
Een andere optie die ik niet heb besproken, maar die voor sommige van uw gegevens nuttig kan zijn, is het opslaan als hash. Dit kan bijvoorbeeld handig zijn voor het opslaan van gedetailleerde informatie over een bepaalde sessie.
Als je de gegevens echt in een database wilt hebben, probeer dan de Pub/Sub-functie van Redis te gebruiken en zorg dat een abonnee de gegevens in een gescheiden formaat parseert en naar een bestand dumpt. Zorg dan voor een importproces dat de kopieeropdracht (of een equivalent voor uw DB) gebruikt om bulksgewijs te importeren. Je database zal je dankbaar zijn.
Een laatste advies hier (ik heb waarschijnlijk al genoeg mentale tijd genomen) is om oordeelkundig en liberaal gebruik te maken van het expiratie-commando. Met Redis 2.2 of nieuwer kunt u de vervaldatum instellen op even tellertoetsen. Het grote voordeel hier is het automatisch opschonen van gegevens. Stel je voor dat je een schema volgt zoals ik hierboven heb geschetst. Door de expiration-commando's te gebruiken, kunt u automatisch oude gegevens opschonen. Misschien wil je statistieken per uur voor maximaal 3 maanden, dan alleen de dagelijkse statistieken; dagelijkse statistieken voor 6 maanden, daarna alleen maandelijkse statistieken. Verval gewoon uw uursleutels na drie maanden (86400*90), uw dagelijkse op 6 (86400*180) en u hoeft niet op te ruimen.
Voor geotagging doe ik offline verwerking van het IP. Stel je een gesorteerde set voor met deze sleutelstructuur:"traffic-by-ip:YYYY-MM-DD" met het IP als het element en met behulp van het hierboven vermelde zinkryby-commando krijg je verkeersgegevens per IP. Nu kunt u in uw rapport de gesorteerde set ophalen en opzoeken van het IP-adres. Om verkeer te besparen wanneer u de rapporten doet, kunt u een hash in redis instellen die het IP-adres toewijst aan de gewenste locatie. Bijvoorbeeld "geo:country" als de sleutel en IP als het hash-lid met de landcode als de opgeslagen waarde.
Een groot voorbehoud dat ik zou willen toevoegen, is dat als je verkeersniveau erg hoog is, je misschien twee exemplaren van Redis wilt gebruiken (of meer, afhankelijk van het verkeer). De eerste zou de schrijfinstantie zijn. De optie bgsave zou niet zijn ingeschakeld. Als uw verkeer behoorlijk hoog is, doet u altijd een bgsave. Dit is waar ik de tweede instantie voor aanbeveel. Het is een slaaf van de eerste en het doet de opslag op schijf. U kunt uw query's ook uitvoeren op de slave om de belasting te verdelen.
Ik hoop dat je wat ideeën en dingen hebt om uit te proberen. Speel met de verschillende opties om te zien wat het beste werkt voor uw specifieke behoeften. Ik volg veel statistieken op een website met veel verkeer (en ook MTA-logstatistieken) in redis en het presteert prachtig - in combinatie met Django en Google's Visualization API krijg ik erg mooi ogende grafieken.