Redis
 sql >> Base de données >  >> NoSQL >> Redis

Un moyen évolutif d'enregistrer les données de demande de page à partir d'une application PHP ?

C'est certainement faisable dans une variété de méthodes. J'aborderai chaque option répertoriée ainsi que quelques commentaires supplémentaires.

1) Si NGinx peut le faire, laissez-le. Je le fais avec Apache ainsi que JBOSS et Tomcat. J'utilise ensuite syslog-ng pour les collecter de manière centralisée et les traiter à partir de là. Pour cet itinéraire, je suggérerais un format de message de journal délimité tel que séparé par des tabulations, car il facilite l'analyse et la lecture. Je ne sais pas s'il enregistre les variables PHP, mais il peut certainement enregistrer les en-têtes et les informations sur les cookies. Si vous envisagez d'utiliser la journalisation NGinx, je recommanderais cette route si possible - pourquoi se connecter deux fois ?

2) Il n'y a pas de "manque de capacité à interroger la date à une date ultérieure", plus bas.

3) Il s'agit d'une option, mais son utilité ou non dépend de la durée pendant laquelle vous souhaitez conserver les données et de la quantité de nettoyage que vous souhaitez écrire. Plus ci-dessous.

4) MongoDB pourrait certainement fonctionner. Vous devrez écrire les requêtes, et ce ne sont pas de simples commandes SQL.

Passons maintenant au stockage des données dans redis. J'enregistre actuellement des choses avec syslog-ng comme indiqué et j'utilise une destination de programme pour analyser les données et les insérer dans Redis. Dans mon cas, j'ai plusieurs critères de regroupement tels que par vhost et par cluster, donc mes structures peuvent être un peu différentes. La question que vous devez d'abord aborder est "quelles données dois-je retirer de ces données" ? Certains d'entre eux seront des compteurs tels que les taux de trafic. Certaines d'entre elles seront des agrégats, et d'autres encore seront des choses comme "ordonner mes pages par popularité".

Je vais vous montrer quelques-unes des techniques permettant d'intégrer facilement cela dans redis (et donc de revenir en arrière).

Tout d'abord, considérons les statistiques de trafic au fil du temps. Décidez d'abord de la granularité. Voulez-vous des statistiques par minute ou des statistiques par heure suffiront-elles ? Voici une façon de suivre le trafic d'une URL donnée :

Stockez les données dans un ensemble trié en utilisant la clé "traffic-by-url:URL:YYYY-MM-DD" dans cet ensemble trié, vous utiliserez la commande zincrby et fournirez le membre "HH:MM". par exemple en Python où "r" est votre connexion redis :

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

Cet exemple augmente le compteur de l'url "/foo.html" le 18 mai à 1h04 du matin.

Pour récupérer les données d'un jour spécifique, vous pouvez appeler zrange sur la clé (""traffic-by-url:URL:YYYY-MM-DD") pour obtenir un ensemble trié du moins populaire au plus populaire. Pour obtenir le top 10 , par exemple, vous utiliseriez zrevrange et lui donneriez la plage. Zrevrange renvoie un tri inversé, le plus grand succès sera en haut. Plusieurs autres commandes d'ensemble triées sont disponibles qui vous permettent de faire de belles requêtes telles que la pagination, obtenir un gamme de résultats par score minimum, etc.

Vous pouvez simplement modifier ou étendre votre nom de clé pour gérer différentes fenêtres temporelles. En combinant cela avec zunionstore, vous pouvez automatiquement passer à des périodes moins granulaires. Par exemple, vous pouvez faire une union de toutes les clés en une semaine ou un mois et stocker dans une nouvelle clé comme "traffic-by-url:monthly:URL:YYYY-MM". En faisant ce qui précède sur toutes les URL d'un jour donné, vous pouvez obtenir quotidiennement. Bien sûr, vous pouvez également avoir une clé de trafic total quotidien et l'incrémenter. Cela dépend principalement du moment où vous souhaitez que les données soient saisies - hors ligne via l'importation du fichier journal ou dans le cadre de l'expérience utilisateur.

Je déconseille de faire grand-chose pendant la session utilisateur réelle car cela prolonge le temps nécessaire à vos utilisateurs pour en faire l'expérience (et la charge du serveur). En fin de compte, ce sera un appel basé sur les niveaux de trafic et les ressources.

Comme vous pouvez l'imaginer, le schéma de stockage ci-dessus peut être appliqué à n'importe quelle statistique basée sur le compteur que vous souhaitez ou déterminez. Par exemple, remplacez l'URL par userID et vous bénéficierez d'un suivi par utilisateur.

Vous pouvez également stocker les journaux bruts dans Redis. Je le fais pour certains journaux en les stockant sous forme de chaînes JSON (je les ai sous forme de paires clé-valeur). Ensuite, j'ai un deuxième processus qui les extrait et fait des choses avec les données.

Pour stocker les hits bruts, vous pouvez également utiliser des ensembles triés en utilisant Epoch Time comme rang et saisir facilement une fenêtre temporelle à l'aide des commandes zrange/zrevrange. Ou stockez-les dans une clé basée sur l'ID utilisateur. Les ensembles fonctionneraient pour cela, tout comme les ensembles triés.

Une autre option dont je n'ai pas parlé, mais qui peut être utile pour certaines de vos données, consiste à stocker sous forme de hachage. Cela peut être utile pour stocker des informations détaillées sur une session donnée par exemple.

Si vous voulez vraiment les données dans une base de données, essayez d'utiliser la fonctionnalité Pub/Sub de Redis et demandez à un abonné de les analyser dans un format délimité et de les vider dans un fichier. Ensuite, ayez un processus d'importation qui utilise la commande de copie (ou l'équivalent pour votre base de données) pour importer en bloc. Votre DB vous remerciera.

Un dernier conseil ici (j'ai probablement déjà pris assez de temps mental) est de faire un usage judicieux et libéral de la commande expire. En utilisant Redis 2.2 ou une version plus récente, vous pouvez définir l'expiration sur des clés de compteur paires. Le gros avantage ici est le nettoyage automatique des données. Imaginez que vous suivez un schéma comme je l'ai décrit ci-dessus. En utilisant les commandes d'expiration, vous pouvez automatiquement purger les anciennes données. Peut-être voulez-vous des statistiques horaires jusqu'à 3 mois, puis uniquement les statistiques quotidiennes ; statistiques quotidiennes pendant 6 mois, puis statistiques mensuelles uniquement. Expirez simplement vos clés horaires après trois mois (86400*90), votre quotidien à 6 (86400*180) et vous n'aurez pas besoin de faire de nettoyage.

Pour la géolocalisation, je fais un traitement hors ligne de l'IP. Imaginez un ensemble trié avec cette structure de clé :"traffic-by-ip:YYYY-MM-DD" en utilisant l'IP comme élément et en utilisant la commande zincryby notée ci-dessus, vous obtenez des données de trafic par IP. Maintenant, dans votre rapport, vous pouvez obtenir l'ensemble trié et effectuer des recherches sur l'adresse IP. Pour économiser du trafic lors de la création de rapports, vous pouvez configurer un hachage dans redis qui mappe l'adresse IP à l'emplacement souhaité. Par exemple "geo:country" comme clé et IP comme membre de hachage avec le code pays comme valeur stockée.

Une grande mise en garde que j'ajouterais est que si votre niveau de trafic est très élevé, vous voudrez peut-être exécuter deux instances de Redis (ou plus selon le trafic). La première serait l'instance d'écriture, elle n'aurait pas l'option bgsave activée. Si votre trafic est assez élevé, vous ferez toujours un bgsave. C'est pour cela que je recommande la deuxième instance. C'est un esclave du premier et il fait les sauvegardes sur disque. Vous pouvez également exécuter vos requêtes sur l'esclave pour répartir la charge.

J'espère que cela vous donnera des idées et des choses à essayer. Jouez avec les différentes options pour voir ce qui fonctionne le mieux pour vos besoins spécifiques. Je suis beaucoup de statistiques sur un site Web à fort trafic (ainsi que les statistiques du journal MTA) dans redis et cela fonctionne à merveille - combiné avec Django et l'API de visualisation de Google, j'obtiens de très beaux graphiques.