sql >> Base de Datos >  >> NoSQL >> Redis

¿Forma escalable de registrar datos de solicitud de página desde una aplicación PHP?

Ciertamente es factible en una variedad de métodos. Abordaré cada opción enumerada, así como algunos comentarios adicionales.

1) Si NGinx puede hacerlo, déjalo. Lo hago con Apache, JBOSS y Tomcat. Luego uso syslog-ng para recopilarlos de forma centralizada y procesarlos desde allí. Para esta ruta, sugeriría un formato de mensaje de registro delimitado, como separado por tabuladores, ya que facilita el análisis y la lectura. No sé si registra variables de PHP, pero ciertamente puede registrar encabezados e información de cookies. Si va a utilizar el registro de NGinx, recomendaría esta ruta si es posible:¿por qué iniciar sesión dos veces?

2) No hay "falta de capacidad para consultar la fecha en una fecha posterior", más abajo.

3) Esta es una opción, pero si es útil o no depende de cuánto tiempo desea conservar los datos y cuánta limpieza desea escribir. Más abajo.

4) MongoDB ciertamente podría funcionar. Tendrá que escribir las consultas, y no son simples comandos SQL.

Ahora, para almacenar los datos en redis. Actualmente registro cosas con syslog-ng como se indica y uso un destino de programa para analizar los datos y meterlos en Redis. En mi caso, tengo varios criterios de agrupación, como por vhost y por clúster, por lo que mis estructuras pueden ser un poco diferentes. La pregunta que debe abordar primero es "¿qué datos quiero de estos datos?" Algunos de ellos serán contadores como las tasas de tráfico. Algunos de ellos serán agregados, y aún más serán cosas como "ordenar mis páginas por popularidad".

Demostraré algunas de las técnicas para poner esto fácilmente en redis (y por lo tanto volver a salir).

Primero, consideremos las estadísticas de tráfico a lo largo del tiempo. Primero decida sobre la granularidad. ¿Quieres estadísticas por minuto o serán suficientes las estadísticas por hora? Esta es una forma de realizar un seguimiento del tráfico de una URL determinada:

Almacene los datos en un conjunto ordenado usando la clave "traffic-by-url:URL:YYYY-MM-DD" en este conjunto ordenado, usará el comando zincrby y proporcionará el miembro "HH:MM". por ejemplo, en Python, donde "r" es su conexión redis:

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

Este ejemplo aumenta el contador de la url "/foo.html" el 18 de mayo a la 1:04 de la mañana.

Para recuperar datos de un día específico, puede llamar a zrange en la clave (""tráfico-por-url:URL:AAAA-MM-DD") para obtener un conjunto ordenado de menos popular a más popular. , por ejemplo, usaría zrevrange y le daría el rango. Zrevrange devuelve una ordenación inversa, el mayor éxito estará en la parte superior. Hay varios comandos de conjuntos más ordenados disponibles que le permiten hacer consultas agradables como paginación, obtener un rango de resultados por puntuación mínima, etc.

Simplemente puede modificar o ampliar el nombre de su clave para manejar diferentes ventanas temporales. Al combinar esto con zunionstore, puede acumular automáticamente períodos de tiempo menos granulares. Por ejemplo, podría hacer una unión de todas las claves en una semana o un mes y almacenarlas en una nueva clave como "tráfico por URL:mensual:URL:AAAA-MM". Al hacer lo anterior en todas las URL en un día determinado, puede obtener diariamente. Por supuesto, también podría tener una clave de tráfico total diario e incrementarla. Depende principalmente de cuándo desea que se ingresen los datos:fuera de línea a través de la importación del archivo de registro o como parte de la experiencia del usuario.

Recomiendo no hacer mucho durante la sesión real del usuario, ya que prolonga el tiempo que tardan los usuarios en experimentarlo (y en la carga del servidor). En última instancia, será una llamada basada en los niveles de tráfico y los recursos.

Como puede imaginar, el esquema de almacenamiento anterior se puede aplicar a cualquier estadística basada en contadores que desee o determine. Por ejemplo, cambie la URL a ID de usuario y tendrá seguimiento por usuario.

También puede almacenar registros sin formato en Redis. Hago esto para algunos registros que los almacenan como cadenas JSON (los tengo como pares clave-valor). Luego tengo un segundo proceso que los extrae y hace cosas con los datos.

Para almacenar hits sin procesar, también puede usar conjuntos ordenados usando Epoch Time como el rango y tomar fácilmente una ventana temporal usando los comandos zrange/zrevrange. O guárdelos en una clave basada en el ID de usuario. Los conjuntos funcionarían para esto, al igual que los conjuntos ordenados.

Otra opción que no he discutido, pero que puede ser útil para algunos de sus datos, es almacenarlos como un hash. Esto podría ser útil para almacenar información detallada sobre una sesión determinada, por ejemplo.

Si realmente quiere los datos en una base de datos, intente usar la función Pub/Sub de Redis y tenga un suscriptor que los analice en un formato delimitado y los vuelque a un archivo. Luego, tenga un proceso de importación que use el comando de copia (o equivalente para su base de datos) para importar en masa. Tu base de datos te lo agradecerá.

Un consejo final aquí (probablemente ya me he tomado suficiente tiempo mental) es hacer un uso juicioso y liberal del comando expire. Con Redis 2.2 o posterior, puede establecer la caducidad incluso en las teclas de contador. La gran ventaja aquí es la limpieza automática de datos. Imagina que sigues un esquema como el que he descrito anteriormente. Al usar los comandos de caducidad, puede purgar automáticamente los datos antiguos. Tal vez desee estadísticas por hora de hasta 3 meses, luego solo las estadísticas diarias; estadísticas diarias durante 6 meses y luego solo estadísticas mensuales. Simplemente caduque sus claves por hora después de tres meses (86400*90), su clave diaria a las 6 (86400*180) y no tendrá que hacer limpieza.

Para el geoetiquetado realizo el procesamiento fuera de línea de la IP. Imagine un conjunto ordenado con esta estructura clave:"tráfico por IP:AAAA-MM-DD" usando la IP como el elemento y usando el comando zincryby mencionado anteriormente para obtener datos de tráfico por IP. Ahora, en su informe, puede obtener el conjunto ordenado y realizar búsquedas de la IP. Para ahorrar tráfico al hacer los informes, puede configurar un hash en redis que asigne la IP a la ubicación que desee. Por ejemplo, "geo:país" como clave e IP como miembro hash con código de país como valor almacenado.

Una gran advertencia que agregaría es que si su nivel de tráfico es muy alto, es posible que desee ejecutar dos instancias de Redis (o más, según el tráfico). La primera sería la instancia de escritura, no tendría habilitada la opción bgsave. Si su tráfico es bastante alto, siempre estará haciendo un bgsave. Para eso recomiendo la segunda instancia. Es un esclavo del primero y hace los guardados en disco. También puede ejecutar sus consultas contra el esclavo para distribuir la carga.

Espero que eso le da algunas ideas y cosas para probar. Juega con las diferentes opciones para ver qué funciona mejor para tus necesidades específicas. Estoy rastreando muchas estadísticas en un sitio web de alto tráfico (y también estadísticas de registro de MTA) en redis y funciona maravillosamente; combinado con Django y la API de visualización de Google, obtengo gráficos muy atractivos.