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

Skalerbar måde at logge sideanmodningsdata fra en PHP-applikation?

Det kan bestemt lade sig gøre på en række forskellige metoder. Jeg vil behandle hver anført mulighed samt nogle yderligere kommentarer.

1) Hvis NGinx kan gøre det, så lad det. Jeg gør det med Apache samt JBOSS og Tomcat. Jeg bruger så syslog-ng til at samle dem centralt og behandle derfra. Til denne rute vil jeg foreslå et afgrænset logmeddelelsesformat såsom tabulatorsepareret, da det gør det nemmere at parse og læse. Jeg ved ikke om det logger PHP-variabler, men det kan helt sikkert logge overskrifter og cookieoplysninger. Hvis du overhovedet skal bruge NGinx-logning, vil jeg anbefale denne rute, hvis det er muligt - hvorfor logge to gange?

2) Der er ingen "manglende mulighed for at forespørge på datoen på et senere tidspunkt", mere nedenfor.

3) Dette er en mulighed, men om det er nyttigt eller ej afhænger af, hvor længe du vil beholde dataene, og hvor meget oprydning du vil skrive. Mere nedenfor.

4) MongoDB kunne bestemt fungere. Du bliver nødt til at skrive forespørgslerne, og de er ikke simple SQL-kommandoer.

Nu til at gemme dataene i redis. Jeg logger i øjeblikket ting med syslog-ng som nævnt og bruger en programdestination til at parse dataene og fylde dem i Redis. I mit tilfælde har jeg flere grupperingskriterier, såsom efter vhost og efter klynge, så mine strukturer kan være lidt anderledes. Spørgsmålet, du skal tage fat på først, er "hvilke data vil jeg have ud af disse data"? Noget af det vil være tællere såsom trafikrater. Noget af det vil være aggregater, og endnu mere vil være ting som "bestil mine sider efter popularitet".

Jeg vil demonstrere nogle af teknikkerne til nemt at få dette til redis (og dermed bakke ud).

Lad os først overveje trafik over tid statistik. Beslut først om granulariteten. Vil du have statistikker pr. minut, eller vil statistikker pr. time være tilstrækkelig? Her er en måde at spore en given URLs trafik:

Gem dataene i et sorteret sæt ved hjælp af nøglen "trafik-efter-url:URL:ÅÅÅÅ-MM-DD" i dette sorterede sæt skal du bruge zincrby-kommandoen og angive medlemmet "TT:MM". for eksempel i Python, hvor "r" er din redis-forbindelse:

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

Dette eksempel øger tælleren for webadressen "/foo.html" den 18. maj kl. 1:04 om morgenen.

For at hente data for en bestemt dag kan du ringe til zrange på tasten (""trafik-efter-url:URL:ÅÅÅÅ-MM-DD") for at få et sorteret sæt fra mindst populær til mest populær. For at få top 10 , for eksempel ville du bruge zrevrange og give det intervallet. Zrevrange returnerer en omvendt sortering, det mest hit vil være øverst. Flere mere sorterede sæt-kommandoer er tilgængelige, som giver dig mulighed for at lave gode forespørgsler såsom paginering, få en række resultater efter minimumscore osv..

Du kan blot ændre eller udvide dit nøglenavn for at håndtere forskellige tidsmæssige vinduer. Ved at kombinere dette med zunionstore kan du automatisk rulle op til mindre detaljerede tidsperioder. For eksempel kan du lave en forening af alle nøgler i en uge eller måned og gemme en ny nøgle som "trafik-for-url:månedlig:URL:ÅÅÅÅ-MM". Ved at gøre ovenstående på alle URL'er på en given dag kan du få dagligt. Du kan selvfølgelig også have en daglig trafiknøgle og øge den. Det afhænger mest af, hvornår du ønsker, at dataene skal indtastes - offline via logfilimport eller som en del af brugeroplevelsen.

Jeg vil anbefale, at du ikke gør meget under selve brugersessionen, da det forlænger den tid, det tager for dine brugere at opleve det (og serverbelastning). I sidste ende vil det være et opkald baseret på trafikniveauer og ressourcer.

Som du kunne forestille dig, kan ovenstående lagringsskema anvendes på enhver tællerbaseret stat, du ønsker eller bestemmer. For eksempel ændre URL til bruger-ID, og ​​du har pr-bruger sporing.

Du kan også opbevare logs rå i Redis. Jeg gør dette for nogle logfiler, der gemmer dem som JSON-strenge (jeg har dem som nøgleværdi-par). Så har jeg en anden proces, der trækker dem ud og gør ting med dataene.

Til lagring af rå hits kan du også bruge et sorteret sæt med Epoch Time som rang og nemt få fat i et tidsmæssigt vindue ved hjælp af zrange/zrevrange kommandoerne. Eller gem dem i en nøgle, der er baseret på bruger-id'et. Sæt ville fungere til dette, ligesom sorterede sæt ville fungere.

En anden mulighed, jeg ikke har diskuteret, men for nogle af dine data kan være nyttig, er lagring som en hash. Dette kan f.eks. være nyttigt til at gemme detaljerede oplysninger om en given session.

Hvis du virkelig vil have dataene i en database, så prøv at bruge Redis' Pub/Sub-funktion og få en abonnent, der analyserer dem i et afgrænset format og dumper til en fil. Lav derefter en importproces, der bruger kopieringskommandoen (eller tilsvarende til din DB) til at importere i bulk. Din DB vil takke dig.

Et sidste råd her (jeg har sikkert allerede brugt nok mental tid) er at gøre en fornuftig og liberal brug af udløbskommandoen. Ved at bruge Redis 2.2 eller nyere kan du indstille udløb på taster med lige tæller. Den store fordel her er automatisk dataoprydning. Forestil dig, at du følger et skema som jeg har skitseret ovenfor. Ved at bruge udløbskommandoer kan du automatisk slette gamle data. Måske vil du have timestatistik i op til 3 måneder, derefter kun den daglige statistik; daglig statistik i 6 måneder derefter kun månedlig statistik. Du skal blot udløbe dine timenøgler efter tre måneder (86400*90), din daglige kl. 6 (86400*180), og du behøver ikke at foretage oprydning.

Til geotagging laver jeg offline behandling af IP'en. Forestil dig et sorteret sæt med denne nøglestruktur:"trafik-for-ip:ÅÅÅÅ-MM-DD" ved at bruge IP'en som element og ved at bruge zincryby-kommandoen nævnt ovenfor får du trafikdata pr. IP. Nu, i din rapport, kan du få det sorterede sæt og foretage opslag af IP'en. For at spare trafik, når du laver rapporterne, kan du oprette en hash i redis, der kortlægger IP'en til den ønskede placering. For eksempel "geo:country" som nøgle og IP som hash-medlem med landekode som den lagrede værdi.

En stor advarsel, jeg vil tilføje, er, at hvis dit trafikniveau er meget højt, vil du måske køre to forekomster af Redis (eller flere afhængigt af trafikken). Den første ville være skriveforekomsten, den ville ikke have bgsave-indstillingen aktiveret. Hvis din trafik er ret høj, vil du altid lave en bgsave. Det er det, jeg anbefaler den anden instans til. Det er en slave til den første, og det gemmer på disken. Du kan også køre dine forespørgsler mod slaven for at fordele belastningen.

Jeg håber, det giver dig nogle ideer og ting, du kan prøve. Leg med de forskellige muligheder for at se, hvad der passer bedst til dine specifikke behov. Jeg sporer en masse statistik på et websted med høj trafik (og også MTA-logstatistik) i redis, og det fungerer smukt - kombineret med Django og Googles Visualization API får jeg meget flotte grafer.



  1. MongoDB $abs

  2. MongoDB-adgangskode med @ i

  3. mongodb:finde den højeste numeriske værdi af en kolonne

  4. Indstil Redis cache-præfiksnøgle på Symfony