Estou desenvolvendo minha própria rede social e não encontrei na web exemplos de implementação o fluxo de ações dos usuários ... Por exemplo, como filtrar ações para cada usuário? Como armazenar os eventos de ação? Qual modelo de dados e modelo de objeto posso usar para o fluxo de ações e para as próprias ações?
design-patterns
architecture
stream
social-networking
Nicolò Martini
fonte
fonte
Respostas:
Resumo : Para cerca de 1 milhão de usuários ativos e 150 milhões de atividades armazenadas, eu simplifico:
Consulte Redis para obter o fluxo de atividades de qualquer usuário e, em seguida, obtenha os dados relacionados do banco de dados, conforme necessário. Volte a consultar o banco de dados por tempo se o usuário precisar navegar muito no tempo (se você oferecer isso)
Eu uso uma tabela antiga simples do MySQL para lidar com cerca de 15 milhões de atividades.
Parece algo como isto:
activity_type
informa o tipo de atividade,source_id
informa o registro ao qual a atividade está relacionada. Portanto, se o tipo de atividade significa "favorito adicionado", eu sei que o source_id se refere ao ID de um registro favorito.Os
parent_id
/parent_type
são úteis para o meu aplicativo - eles me dizem a que a atividade está relacionada. Se um livro fosse favorito, parent_id / parent_type me diria que a atividade está relacionada a um livro (tipo) com uma determinada chave primária (id)Eu indexo
(user_id, time)
e procuro atividades que sãouser_id IN (...friends...) AND time > some-cutoff-point
. Abandonar o ID e escolher um índice em cluster diferente pode ser uma boa ideia - não experimentei isso.Coisas bastante básicas, mas funcionam, são simples e são fáceis de trabalhar conforme as suas necessidades mudam. Além disso, se você não estiver usando o MySQL, poderá executar melhor em termos de índice.
Para acesso mais rápido às atividades mais recentes, experimentei o Redis . O Redis armazena todos os seus dados na memória, para que você não possa colocar todas as suas atividades nele, mas pode armazenar o suficiente para a maioria das telas mais comuns do seu site. Os 100 mais recentes para cada usuário ou algo parecido. Com Redis na mistura, pode funcionar assim:
O Redis é rápido e oferece uma maneira de canalizar comandos através de uma conexão - assim, enviar uma atividade para 1.000 amigos leva milissegundos.
Para uma explicação mais detalhada do que estou falando, consulte o exemplo do Redis no Twitter: http://redis.io/topics/twitter-clone
Atualização em fevereiro de 2011 Eu tenho 50 milhões de atividades ativas no momento e não mudei nada. Uma coisa legal de fazer algo semelhante a isso é que ele usa linhas pequenas e compactas. Estou planejando fazer algumas mudanças que envolvam muito mais atividades e mais consultas dessas atividades, e definitivamente utilizarei o Redis para manter as coisas rápidas. Estou usando o Redis em outras áreas e realmente funciona bem para certos tipos de problemas.
Atualização julho de 2014 Temos cerca de 700 mil usuários ativos mensais. Nos últimos dois anos, tenho usado o Redis (como descrito na lista com marcadores) para armazenar os últimos 1000 IDs de atividade para cada usuário. Geralmente, existem cerca de 100 milhões de registros de atividades no sistema e eles ainda estão armazenados no MySQL e ainda têm o mesmo layout. Esses registros nos permitem gastar menos memória Redis, eles servem como o registro dos dados da atividade e os usamos se os usuários precisarem voltar mais no tempo para encontrar algo.
Esta não foi uma solução inteligente ou especialmente interessante, mas me serviu bem.
fonte
JOIN
nas váriasactivity_type
tabelas? Essas junções são caras em termos de desempenho?activity_type
para obter os outros dados necessários.Esta é a minha implementação de um fluxo de atividades, usando o mysql. Existem três classes: Activity, ActivityFeed, Subscriber.
Activity representa uma entrada de atividade e sua tabela fica assim:
Subject_id
é o ID do objeto que está executando a ação,object_id
o ID do objeto que recebe a ação.type
everb
descreve a ação em si (por exemplo, se um usuário adicionar um comentário a um artigo, ele seria "comment" e "created" respectivamente), os dados conterão dados adicionais para evitar junções (por exemplo, ele pode conter o nome do assunto e sobrenome, título e URL do artigo, corpo do comentário etc.).Cada atividade pertence a um ou mais ActivityFeeds e são relacionados por uma tabela que se parece com isso:
No meu aplicativo, tenho um feed para cada usuário e um feed para cada item (geralmente artigos de blog), mas eles podem ser o que você quiser.
Um Assinante geralmente é um usuário do seu site, mas também pode ser qualquer objeto no seu modelo de objeto (por exemplo, um artigo pode ser inscrito na feed_action do criador).
Cada Assinante pertence a um ou mais ActivityFeeds e, como acima, são relacionados por uma tabela de links desse tipo:
O
reason
campo aqui explica por que o assinante assinou o feed. Por exemplo, se um usuário marcar uma postagem de blog, o motivo é "marcador". Isso me ajuda mais tarde a filtrar ações para notificações aos usuários.Para recuperar a atividade de um assinante, faço uma junção simples das três tabelas. A junção é rápida porque seleciono poucas atividades graças a uma
WHERE
condição que parece agora -time > some hours
. Evito outras junções graças ao campo de dados na tabela Atividade.Mais explicações em
reason
campo. Se, por exemplo, quero filtrar ações para notificações por email ao usuário e o usuário marcou uma postagem de blog (e, portanto, ele assina o feed da postagem com o motivo 'marcador'), não quero que o usuário receba enviar notificações por e-mail sobre ações nesse item, enquanto se ele comentar a postagem (e, por isso, assinar o feed da postagem com o motivo 'comentar'), desejo que ele seja notificado quando outros usuários adicionarem comentários à mesma postagem. O campo de razão me ajuda nessa discriminação (eu a implementei por meio de uma classe ActivityFilter), juntamente com as preferências de notificações do usuário.fonte
Existe um formato atual para o fluxo de atividades que está sendo desenvolvido por várias pessoas conhecidas.
http://activitystrea.ms/ .
Basicamente, toda atividade tem um ator (que executa a atividade), um verbo (a ação da atividade), um objeto (no qual o ator atua) e um alvo.
Por exemplo: Max postou um link no mural de Adam.
As especificações do JSON atingiram a versão 1.0 no momento da redação, que mostra o padrão para a atividade que você pode aplicar.
Seu formato já foi adotado pela BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID e muitos outros.
fonte
Eu acho que uma explicação sobre como o sistema de notificações funciona em sites grandes pode ser encontrada na pergunta sobre estouro de pilha. Como os sites de redes sociais calculam as atualizações de amigos? , na resposta de Jeremy Wall . Ele sugere o uso do Message Qeue e indica dois softwares de código aberto que o implementam:
Veja também a pergunta Qual é a melhor maneira de implementar um fluxo de atividades sociais?
fonte
Você absolutamente precisa de um desempenho e fila de mensagens distribuídas. Mas não termina aí, você terá que tomar decisões sobre o que armazenar como dados persistentes e o que são transitórios e etc.
Enfim, é realmente uma tarefa difícil, meu amigo, se você está atrás de um sistema escalável e de alto desempenho. Mas, é claro, alguns engenheiros generosos compartilharam sua experiência sobre isso. O LinkedIn recentemente criou seu sistema de fila de mensagens Kafka de código aberto. Antes disso, o Facebook já havia fornecido o Scribe à comunidade de código aberto. O Kafka é escrito em Scala e, inicialmente, leva algum tempo para ser executado, mas eu testei com alguns servidores virtuais. É muito rápido.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
http://incubator.apache.org/kafka/index.html
fonte
Em vez de criar o seu próprio, você pode procurar um serviço de terceiros usado por meio de uma API. Comecei um chamado Collabinate ( http://www.collabinate.com ), que possui um back-end de banco de dados de gráficos e alguns algoritmos bastante sofisticados para lidar com grandes quantidades de dados de maneira altamente simultânea e de alto desempenho. Embora não tenha a amplitude de funcionalidade que o Facebook ou o Twitter possuem, é mais do que suficiente para a maioria dos casos de uso em que você precisa criar fluxos de atividade, feeds sociais ou funcionalidade de microblog em um aplicativo.
fonte