Estou interessado em ouvir suas opiniões sobre qual é a melhor maneira de implementar um fluxo de atividades sociais (o Facebook é o exemplo mais famoso). Os problemas / desafios envolvidos são:
- Diferentes tipos de atividades (postagem, comentário ..)
- Diferentes tipos de objetos (publicação, comentário, foto ..)
- 1-n usuários envolvidos em diferentes funções ("O usuário x respondeu ao comentário do usuário y na publicação Z do usuário")
- Exibições diferentes do mesmo item de atividade ("você comentou .." vs. "seu amigo x comentou" vs. "usuário x comentou .." => 3 representações de uma atividade "comentar")
.. e mais alguns, especialmente se você o elevar a um alto nível de sofisticação, como o Facebook, por exemplo, combinando vários itens de atividade em um ("usuários x, yez comentaram sobre essa foto"
Serão apreciados quaisquer pensamentos ou sugestões sobre padrões, documentos, etc., sobre as abordagens mais flexíveis, eficientes e poderosas para implementar esse sistema, modelo de dados etc.
Embora a maioria dos problemas seja independente de plataforma, é provável que eu acabe implementando esse sistema no Ruby on Rails
fonte
Esta é uma apresentação muito boa, descrevendo como o Etsy.com arquitetou seus fluxos de atividades. É o melhor exemplo que encontrei sobre o tópico, embora não seja específico dos trilhos.
http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture
fonte
Abrimos nossa abordagem de código aberto: https://github.com/tschellenbach/Stream-Framework Atualmente, é a maior biblioteca de código aberto voltada para a solução desse problema.
A mesma equipe que criou o Stream Framework também oferece uma API hospedada, que lida com a complexidade para você. Dê uma olhada no getstream.io Existem clientes disponíveis para Node, Python, Rails e PHP.
Além disso, dê uma olhada neste post de alta escalabilidade, onde explicamos algumas das decisões de design envolvidas: http://highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic- feeds.html
Este tutorial irá ajudá-lo a configurar um sistema como o feed do Pinterest usando Redis. É muito fácil começar.
Para saber mais sobre o design de feeds, recomendo a leitura de alguns dos artigos nos quais baseamos o Feedly:
Embora o Stream Framework seja baseado em Python, não seria muito difícil de usar em um aplicativo Ruby. Você pode simplesmente executá-lo como um serviço e colocar uma pequena API http na frente dele. Estamos pensando em adicionar uma API para acessar o Feedly de outros idiomas. No momento, você terá que fazer o seu próprio papel.
fonte
Os maiores problemas com fluxos de eventos são visibilidade e desempenho; você precisa restringir os eventos exibidos para serem apenas os interessantes para esse usuário específico e manter o tempo necessário para classificar e identificar esses eventos gerenciáveis. Eu construí uma rede social pequena; Eu descobri que, em pequenas escalas, manter uma tabela de "eventos" em um banco de dados funciona, mas isso pode ser um problema de desempenho sob carga moderada.
Com um fluxo maior de mensagens e usuários, provavelmente é melhor usar um sistema de mensagens, no qual os eventos são enviados como mensagens para perfis individuais. Isso significa que você não pode se inscrever facilmente nos fluxos de eventos das pessoas e ver os eventos anteriores com muita facilidade, mas você está simplesmente processando um pequeno grupo de mensagens quando precisa processar o fluxo para um usuário específico.
Acredito que essa foi a falha de design original do Twitter - lembro-me de ler que eles estavam acessando o banco de dados para extrair e filtrar seus eventos. Isso tinha tudo a ver com arquitetura e nada com Rails, que (infelizmente) deu origem ao meme "rubi não escala". Recentemente, vi uma apresentação em que o desenvolvedor usou o Simple Queue Service da Amazon como back-end de mensagens para um aplicativo semelhante ao twitter que teria recursos de dimensionamento muito mais altos - pode valer a pena examinar o SQS como parte do seu sistema, se suas cargas forem altas o suficiente .
fonte
Se você estiver disposto a usar um software separado, sugiro o servidor Graphity, que resolve exatamente o problema dos fluxos de atividades (construindo sobre o banco de dados de gráficos neo4j).
Os algoritmos foram implementados como um servidor REST independente, para que você possa hospedar seu próprio servidor para fornecer fluxos de atividades: http://www.rene-pickhardt.de/graphity-server-for-social-activity-streams-released-gplv3 /
No artigo e no benchmark, mostrei que a recuperação de fluxos de notícias depende apenas linearmente da quantidade de itens que você deseja recuperar sem nenhuma redundância que você obteria ao desnormalizar os dados:
http://www.rene-pickhardt.de/graphity-an-efficient-graph-model-for-retrieving-the-top-k-news-feeds-for-users-in-social-networks/
No link acima, você encontra screencasts e uma referência dessa abordagem (mostrando que a graphity é capaz de recuperar mais de 10 mil fluxos por segundo).
fonte
Comecei a implementar um sistema como este ontem, aqui é onde eu tenho que ...
Criei uma classe StreamEvent com as propriedades Id , ActorId , TypeId , Date , ObjectId e uma hashtable de pares chave / valor adicionais de detalhes . Isto é representado no banco de dados por um StreamEvent mesa ( Id , ActorID , TypeId , Data , ObjectId ) e um StreamEventDetails mesa ( StreamEventId , DetailKey , DetailValue ).
O ActorId , TypeId e ObjectId permitem que um evento Subject-Verb-Object seja capturado (e consultado posteriormente). Cada ação pode resultar na criação de várias instâncias StreamEvent.
Criei uma subclasse para StreamEvent para cada tipo de evento, por exemplo , LoginEvent , PictureCommentEvent . Cada uma dessas subclasses possui mais propriedades específicas de contexto, como PictureId , ThumbNail , CommenText , etc (o que for necessário para o evento) que são realmente armazenadas como pares de chave / valor na tabela hashtable / StreamEventDetail.
Ao recuperar esses eventos do banco de dados, uso um método de fábrica (baseado no TypeId ) para criar a classe StreamEvent correta.
Cada subclasse de StreamEvent possui um método Render ( context As StreamContext ) que gera o evento para a tela com base na classe StreamContext passada . A classe StreamContext permite que as opções sejam definidas com base no contexto da exibição. Se você olhar para o Facebook, por exemplo, seu feed de notícias na página inicial lista os nomes completos (e os links para o perfil) de todos os envolvidos em cada ação, enquanto, ao procurar o feed de um amigo, você vê apenas o primeiro nome (mas o nome completo de outros atores) .
Ainda não implementei um feed agregado (página inicial do Facebook), mas imagino que vou criar uma tabela AggregateFeed com os campos UserId , StreamEventId preenchidos com base em algum tipo de algoritmo 'Hmmm, você pode achar interessante'.
Quaisquer comentários serão muito apreciados.
fonte
Quando o evento for criado, decida em quais feeds ele aparecerá e adicione-o a events_feeds. Para obter um feed, selecione entre events_feeds, participe de eventos, ordene pelo carimbo de data / hora. A filtragem e a agregação podem ser feitas nos resultados dessa consulta. Com este modelo, você pode alterar as propriedades do evento após a criação, sem trabalho extra.
fonte
Se você decidir implementar no Rails, talvez você ache o seguinte plugin útil:
ActivityStreams: http://github.com/face/activity_streams/tree/master
Se nada mais, você verá uma implementação, tanto em termos do modelo de dados quanto da API fornecida para atividades de envio e recebimento.
fonte
Eu tive uma abordagem semelhante à do heyman - uma tabela desnormalizada contendo todos os dados que seriam exibidos em um determinado fluxo de atividades. Funciona bem para um site pequeno com atividade limitada.
Como mencionado acima, é provável que haja problemas de escalabilidade à medida que o site cresce. Pessoalmente, não estou preocupado com os problemas de dimensionamento no momento. Vou me preocupar com isso mais tarde.
Obviamente, o Facebook fez um ótimo trabalho de dimensionamento, então eu recomendo que você leia o blog de engenharia, pois ele possui uma grande quantidade de conteúdo -> http://www.facebook.com/notes.php?id=9445547199
Tenho procurado soluções melhores do que a tabela desnormalizada que mencionei acima. Outra maneira que encontrei para realizar isso é condensar todo o conteúdo que estaria em um determinado fluxo de atividades em uma única linha. Ele pode ser armazenado em XML, JSON ou em algum formato serializado que possa ser lido pelo seu aplicativo. O processo de atualização também seria simples. Após a atividade, coloque a nova atividade em uma fila (talvez usando o Amazon SQS ou outra coisa) e, em seguida, pesquise continuamente a fila para o próximo item. Pegue esse item, analise-o e coloque seu conteúdo no objeto de feed apropriado armazenado no banco de dados.
A coisa boa desse método é que você só precisa ler uma única tabela de banco de dados sempre que esse feed específico for solicitado, em vez de pegar uma série de tabelas. Além disso, ele permite que você mantenha uma lista finita de atividades, pois pode sair do item de atividade mais antigo sempre que atualizar a lista.
Espero que isto ajude! :)
fonte
Existem dois railscasts sobre esse fluxo de atividades:
Essas soluções não incluem todos os seus requisitos, mas devem fornecer algumas idéias.
fonte
Eu acho que o Plurk abordagem é interessante: eles fornecem toda a linha do tempo em um formato que se parece muito com os gráficos de ações do Google Finance.
Pode valer a pena olhar para Ning para ver como funciona uma rede de rede social. As páginas do desenvolvedor parecem especialmente úteis.
fonte
Resolvi isso alguns meses atrás, mas acho que minha implementação é muito básica.
Criei os seguintes modelos:
Exemplo
fonte
Após implementar fluxos de atividades para habilitar feeds sociais, microblogs e recursos de colaboração em vários aplicativos, percebi que a funcionalidade básica é bastante comum e poderia ser transformada em um serviço externo que você utiliza por meio de uma API. Se você estiver criando o fluxo em um aplicativo de produção e não tiver necessidades únicas ou profundamente complexas, utilizar um serviço comprovado pode ser o melhor caminho a percorrer. Definitivamente, eu recomendaria isso para aplicativos de produção, rolando sua própria solução simples sobre um banco de dados relacional.
Minha empresa Collabinate ( http://www.collabinate.com ) cresceu com essa percepção e implementamos um mecanismo de fluxo de atividades escalável e de alto desempenho no topo de um banco de dados gráfico para alcançá-lo. Na verdade, utilizamos uma variante do algoritmo Graphity (adaptado do trabalho inicial de @RenePickhardt, que também forneceu uma resposta aqui) para construir o mecanismo.
Se você deseja hospedar o mecanismo você mesmo ou precisar de uma funcionalidade especializada, o código principal é realmente de código aberto para fins não comerciais, portanto, você pode dar uma olhada.
fonte