Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Maneira escalável de registrar dados de solicitação de página de um aplicativo PHP?


É certamente factível em uma variedade de métodos. Vou abordar cada opção listada, bem como alguns comentários adicionais.

1) Se o NGinx pode fazer isso, deixe. Eu faço isso com Apache assim como JBOSS e Tomcat. Em seguida, uso o syslog-ng para coletá-los centralmente e processá-los a partir daí. Para essa rota, sugiro um formato de mensagem de log delimitado, como separado por tabulação, pois facilita a análise e a leitura. Eu não sei sobre isso registrar variáveis ​​PHP, mas certamente pode registrar cabeçalhos e informações de cookies. Se você for usar o log do NGinx, eu recomendaria essa rota, se possível - por que logar duas vezes?

2) Não há "falta de capacidade de consultar a data em uma data posterior", mais abaixo.

3) Esta é uma opção, mas se é útil ou não depende de quanto tempo você deseja manter os dados e quanta limpeza deseja gravar. Mais abaixo.

4) MongoDB certamente poderia funcionar. Você terá que escrever as consultas, e elas não são comandos SQL simples.

Agora, para armazenar os dados em redis. Atualmente, registro coisas com syslog-ng conforme observado e uso um destino de programa para analisar os dados e colocá-los no Redis. No meu caso, tenho vários critérios de agrupamento, como por vhost e por cluster, então minhas estruturas podem ser um pouco diferentes. A pergunta que você precisa abordar primeiro é "que dados eu quero desses dados"? Alguns deles serão contadores, como taxas de tráfego. Alguns deles serão agregados, e mais ainda serão coisas como "ordenar minhas páginas por popularidade".

Demonstrarei algumas das técnicas para colocar isso facilmente no redis (e, assim, voltar).

Primeiro, vamos considerar as estatísticas de tráfego ao longo do tempo. Primeiro decida sobre a granularidade. Você quer estatísticas por minuto ou estatísticas por hora são suficientes? Aqui está uma maneira de rastrear o tráfego de um determinado URL:

Armazene os dados em um conjunto classificado usando a chave "traffic-by-url:URL:YYYY-MM-DD" neste conjunto classificado você usará o comando zincrby e fornecerá o membro "HH:MM". por exemplo em Python onde "r' é sua conexão redis:
r.zincrby("traffic-by-url:/foo.html:2011-05-18", "01:04",1)

Este exemplo aumenta o contador da url "/foo.html" no dia 18 de maio às 1:04 da manhã.

Para recuperar dados de um dia específico, você pode chamar zrange na chave (""traffic-by-url:URL:YYYY-MM-DD") para obter um conjunto classificado do menos popular para o mais popular. Para obter os 10 principais , por exemplo, você usaria zrevrange e daria a ele o intervalo. Zrevrange retorna uma classificação reversa, o maior número de acertos estará no topo. Vários comandos de conjunto mais ordenados estão disponíveis que permitem fazer consultas interessantes, como paginação, obter um gama de resultados por pontuação mínima, etc.

Você pode simplesmente alterar ou estender seu nome de chave para lidar com diferentes janelas temporais. Ao combinar isso com o zunionstore, você pode fazer roll-up automaticamente para períodos de tempo menos granulares. Por exemplo, você pode fazer uma união de todas as chaves em uma semana ou mês e armazenar em uma nova chave como "traffic-by-url:monthly:URL:YYYY-MM". Ao fazer o acima em todos os URLs em um determinado dia, você pode obter diariamente. Claro, você também pode ter uma chave de tráfego total diária e incrementá-la. Depende principalmente de quando você deseja que os dados sejam inseridos - offline por meio de importação de arquivo de log ou como parte da experiência do usuário.

Eu não recomendo fazer muito durante a sessão real do usuário, pois isso aumenta o tempo que leva para que seus usuários a experimentem (e carga do servidor). Em última análise, essa será uma chamada baseada nos níveis de tráfego e recursos.

Como você pode imaginar, o esquema de armazenamento acima pode ser aplicado a qualquer estatística baseada em contador que você deseja ou determina. Por exemplo, altere o URL para userID e você terá rastreamento por usuário.

Você também pode armazenar logs brutos no Redis. Eu faço isso para alguns logs armazenando-os como strings JSON (eu os tenho como pares de valores-chave). Então eu tenho um segundo processo que os retira e faz coisas com os dados.

Para armazenar hits brutos, você também pode usar conjuntos ordenados usando o Epoch Time como a classificação e facilmente pegar uma janela temporal usando os comandos zrange/zrevrange. Ou armazene-os em uma chave baseada no ID do usuário. Conjuntos funcionariam para isso, assim como conjuntos ordenados.

Outra opção que não discuti, mas para alguns de seus dados pode ser útil, é armazenar como hash. Isso pode ser útil para armazenar informações detalhadas sobre uma determinada sessão, por exemplo.

Se você realmente deseja os dados em um banco de dados, tente usar o recurso Pub/Sub do Redis e tenha um assinante que os analise em um formato delimitado e despeje em um arquivo. Em seguida, tenha um processo de importação que use o comando copy (ou equivalente para seu banco de dados) para importar em massa. Seu DB vai agradecer.

Um conselho final aqui (provavelmente já gastei bastante tempo mental) é fazer uso criterioso e liberal do comando expire. Usando o Redis 2.2 ou mais recente, você pode definir a expiração em chaves de contador iguais. A grande vantagem aqui é a limpeza automática de dados. Imagine que você segue um esquema como eu descrevi acima. Ao usar os comandos de expiração, você pode limpar automaticamente os dados antigos. Talvez você queira estatísticas por hora por até 3 meses, depois apenas as estatísticas diárias; estatísticas diárias por 6 meses, depois apenas estatísticas mensais. Simplesmente expire suas chaves horárias após três meses (86400*90), sua diária às 6 (86400*180) e você não precisará fazer a limpeza.

Para geotagging eu faço o processamento offline do IP. Imagine um conjunto ordenado com esta estrutura de chave:"traffic-by-ip:YYYY-MM-DD" usando o IP como o elemento e usando o comando zincryby mencionado acima, você obtém dados de tráfego por IP. Agora, em seu relatório, você pode obter o conjunto classificado e fazer pesquisas do IP. Para economizar tráfego ao fazer os relatórios, você pode configurar um hash no redis que mapeia o IP para o local desejado. Por exemplo, "geo:country" como chave e IP como membro de hash com código de país como valor armazenado.

Uma grande ressalva que eu acrescentaria é que, se o seu nível de tráfego for muito alto, talvez você queira executar duas instâncias do Redis (ou mais, dependendo do tráfego). A primeira seria a instância de escrita, não teria a opção bgsave habilitada. Se o seu tráfego for muito alto, você sempre estará fazendo um bgsave. É para isso que eu recomendo a segunda instância. É escravo do primeiro e faz os saves em disco. Você também pode executar suas consultas no escravo para distribuir a carga.

Espero que isso lhe dê algumas idéias e coisas para experimentar. Brinque com as diferentes opções para ver o que funciona melhor para suas necessidades específicas. Estou rastreando muitas estatísticas em um site de alto tráfego (e também estatísticas de log do MTA) no redis e ele funciona lindamente - combinado com o Django e a API de visualização do Google, recebo gráficos muito bonitos.