sql >> Databasteknik >  >> NoSQL >> Redis

Skalbart sätt att logga sidförfrågningsdata från en PHP-applikation?

Det är säkert genomförbart i en mängd olika metoder. Jag kommer att ta upp varje listat alternativ samt några ytterligare kommentarer.

1) Om NGinx kan göra det, låt det. Jag gör det med Apache samt JBOSS och Tomcat. Jag använder sedan syslog-ng för att samla in dem centralt och bearbeta därifrån. För den här rutten skulle jag föreslå ett avgränsat loggmeddelandeformat som tabbavgränsat eftersom det gör det lättare att analysera och läsa. Jag vet inte om det loggar PHP-variabler, men det kan säkert logga rubriker och cookieinformation. Om du överhuvudtaget ska använda NGinx-loggning skulle jag rekommendera den här vägen om möjligt - varför logga två gånger?

2) Det finns ingen "brist på möjligheten att fråga efter datumet vid ett senare tillfälle", mer nedan.

3) Detta är ett alternativ men om det är användbart eller inte beror på hur länge du vill behålla data och hur mycket rensning du vill skriva. Mer nedan.

4) MongoDB skulle säkert kunna fungera. Du måste skriva frågorna, och de är inte enkla SQL-kommandon.

Nu, till att lagra data i redis. Jag loggar för närvarande saker med syslog-ng som noterat och använder en programdestination för att analysera data och stoppa in den i Redis. I mitt fall har jag flera grupperingskriterier som efter vhost och efter kluster, så mina strukturer kan vara lite annorlunda. Frågan du måste lösa först är "vilken data vill jag ha ut av denna data"? En del av det kommer att vara räknare som trafikpriser. En del av det kommer att vara aggregat, och ännu mer kommer att vara saker som "ordna mina sidor efter popularitet".

Jag kommer att demonstrera några av teknikerna för att enkelt få detta till redis (och därmed backa ut).

Låt oss först överväga statistiken över trafik över tid. Bestäm först granulariteten. Vill du ha statistik per minut eller räcker det med statistik per timme? Här är ett sätt att spåra en given webbadress trafik:

Lagra data i en sorterad uppsättning med nyckeln "trafik-efter-url:URL:ÅÅÅÅ-MM-DD" i denna sorterade uppsättning kommer du att använda zincrby-kommandot och ange medlemmen "TT:MM". till exempel i Python där "r" är din redis-anslutning:

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

Det här exemplet ökar räknaren för webbadressen "/foo.html" den 18 maj klockan 1:04 på morgonen.

För att hämta data för en specifik dag kan du ringa zrange på tangenten (""trafik-efter-url:URL:ÅÅÅÅ-MM-DD") för att få en sorterad uppsättning från minst populär till mest populär. För att få topp 10 , till exempel skulle du använda zrevrange och ge det intervallet. Zrevrange returnerar en omvänd sortering, den mest träffade kommer att vara överst. Flera mer sorterade set-kommandon finns tillgängliga som låter dig göra snygga frågor som sidnumrering, få en resultatintervall efter lägsta poäng osv.

Du kan helt enkelt ändra eller utöka ditt nyckelnamn för att hantera olika tidsmässiga fönster. Genom att kombinera detta med zunionstore kan du automatiskt rulla upp till mindre granulära tidsperioder. Du kan till exempel göra en sammanslutning av alla nycklar under en vecka eller månad och lagra i en ny nyckel som "trafik-för-url:månad:URL:ÅÅÅÅ-MM". Genom att göra ovanstående på alla webbadresser under en viss dag kan du få dagligen. Naturligtvis kan du också ha en daglig total trafiknyckel och öka den. Det beror mest på när du vill att data ska matas in - offline via loggfilimport eller som en del av användarupplevelsen.

Jag skulle rekommendera att inte göra mycket under själva användarsessionen eftersom det förlänger tiden det tar för dina användare att uppleva det (och serverbelastning). I slutändan blir det ett samtal baserat på trafiknivåer och resurser.

Som du kan föreställa dig kan ovanstående lagringsschema tillämpas på vilken räknarebaserad statistik du vill eller bestämmer. Ändra till exempel URL till användar-ID och du har spårning per användare.

Du kan också lagra stockar råa i Redis. Jag gör detta för vissa loggar som lagrar dem som JSON-strängar (jag har dem som nyckel-värdepar). Sedan har jag en andra process som drar ut dem och gör saker med datan.

För att lagra råträffar kan du också använda sorterade set med Epoch Time som rang och enkelt ta ett tidsfönster med hjälp av zrange/zrevrange-kommandona. Eller lagra dem i en nyckel som är baserad på användar-ID. Uppsättningar skulle fungera för detta, liksom sorterade uppsättningar.

Ett annat alternativ som jag inte har diskuterat men för vissa av dina data kan vara användbart är att lagra som en hash. Detta kan till exempel vara användbart för att lagra detaljerad information om en given session.

Om du verkligen vill ha data i en databas, försök att använda Redis Pub/Sub-funktion och ha en prenumerant som analyserar den till ett avgränsat format och dumpar till en fil. Ha sedan en importprocess som använder kopieringskommandot (eller motsvarande för din DB) för att importera i bulk. Din DB kommer att tacka dig.

Ett sista råd här (jag har antagligen redan tagit mig tillräckligt med mental tid) är att använda kommandot expire på ett klokt och liberalt sätt. Med Redis 2.2 eller nyare kan du ställa in utgångsdatum på nycklar med jämna räknare. Den stora fördelen här är automatisk datarensning. Föreställ dig att du följer ett schema som jag har beskrivit ovan. Genom att använda utgångskommandona kan du automatiskt rensa gamla data. Kanske vill du ha timstatistik i upp till 3 månader, sedan bara den dagliga statistiken; daglig statistik för 6 månader sedan endast månadsstatistik. Förfall helt enkelt dina timnycklar efter tre månader (86400*90), din dagliga kl. 6 (86400*180) så behöver du inte städa.

För geotaggning gör jag offline-bearbetning av IP:n. Föreställ dig en sorterad uppsättning med denna nyckelstruktur:"trafik-för-ip:ÅÅÅÅ-MM-DD" med IP:n som element och med hjälp av zincryby-kommandot ovan får du trafikdata per IP. Nu, i din rapport, kan du få den sorterade uppsättningen och göra uppslagningar av IP:n. För att spara trafik när du gör rapporterna kan du ställa in en hash i redis som mappar IP:n till den plats du vill ha. Till exempel "geo:country" som nyckel och IP som hashmedlem med landskod som lagrat värde.

En stor varning som jag vill tillägga är att om din trafiknivå är mycket hög kanske du vill köra två instanser av Redis (eller fler beroende på trafik). Den första skulle vara skrivinstansen, den skulle inte ha alternativet bgsave aktiverat. Om din trafik är ganska hög kommer du alltid att göra en bgsave. Detta är vad jag rekommenderar den andra instansen för. Det är en slav till den första och sparar till disk. Du kan också köra dina frågor mot slaven för att fördela lasten.

Jag hoppas att det ger dig några idéer och saker att testa. Spela runt med de olika alternativen för att se vad som fungerar bäst för dina specifika behov. Jag spårar mycket statistik på en webbplats med hög trafik (och även MTA-loggstatistik) i redis och den presterar vackert - i kombination med Django och Googles Visualization API får jag mycket snygga grafer.



  1. Spring Boot redis Template autokabelkoppling misslyckades

  2. Är redis en hållbar databutik?

  3. Det går inte att ansluta till Redis-servern med ASP.NET Session State Provider

  4. MongoDB E11000 dubblettnyckelfel