Sistema de notificação de redes sociais


10

fundo

Estou trabalhando em um aplicativo para um cliente que inclui alguns recursos de redes sociais. Eu estava originalmente desenvolvendo o front-end móvel, mas as circunstâncias me deixaram encarregado de desenvolver o back-end também.

Como pano de fundo geral, nosso sistema permite que os usuários sigam outros usuários e recebam notificações sobre aqueles que estão seguindo, como seria de esperar de uma rede social. Uma ressalva é que apenas um pequeno subconjunto (no máximo algumas centenas) de usuários será seguido, com a expectativa de que a maior parte da base de usuários esteja seguindo pelo menos um desses indivíduos.

No lado da interface do usuário, teremos um botão de notificação com um número e, ao clicar no botão, você será levado à tela de notificação.

O problema

Pesquisei estratégias para implementar notificações e a maioria dos recursos que encontrei apontam para a criação de uma ou mais tabelas de notificação no banco de dados. (Um exemplo que eu gosto é a resposta aceita aqui: /programming/9735578/building-a-notification-system ).

O que me impressiona é que a maioria das estratégias de notificações direcionadas ao banco de dados exige a inserção de uma linha para cada notificação para cada seguidor. Portanto, se mil pessoas estiverem seguindo Sally, inseriremos mil linhas na tabela correspondente. Isso é escalável? O que acontece se chegarmos ao ponto em que dezenas ou centenas de milhares de usuários estão seguindo Sally e ela está fazendo algumas dezenas de postagens por dia?

Minha idéia original era lidar com tudo com consultas: o número no botão de notificação seria obtido solicitando contagens de linhas no conteúdo postado mais recentemente do que na última vez em que você visitou a tela de notificação, enquanto notificações individuais seriam geradas a partir de consultas mais detalhadas quando você visitou a tela de notificação. Essa abordagem não requer gravações ou armazenamento extra, mas é inflexível e provavelmente prejudicaria bastante o servidor.

CONFIGURAÇÃO

O back-end (conforme estabelecido pelo desenvolvedor anterior) usa o CodeIgniter e um banco de dados MySQL . Atualmente, ele está sendo executado em uma conta de hospedagem compartilhada ruim do GoDaddy, mas suponho (espero?) Que isso será atualizado antes de entrarmos em produção e que o pacote de hospedagem será escalado com o crescimento do usuário.

Atualmente, nosso único front-end é um aplicativo móvel, mas também planejamos criar um site posteriormente. No momento, não estou preocupado em obter atualizações por push em tempo real do servidor sobre as notificações.

TERMO ADITIVO

Eu não me especializo em back-end e estou em minha cabeça naquele departamento. O cliente sabe disso, e eu fiz o meu melhor para tentar explicar o escopo de um projeto dessa natureza, mas eles deixaram claro que, nesse ponto, não confiarão em mais ninguém para trabalhar no projeto. Provavelmente temos mais um mês de trabalho para começar a adicionar testadores e eu posso obter qualquer tipo de métrica de desempenho. Realmente não posso estimar quantos usuários poderemos ter ou em que hardware estaremos nos próximos cinco anos, mas acho que o cliente está esperando por centenas de milhares de usuários ou mais.

Espero que este seja um problema específico o suficiente para ser postado aqui; Eu posso refinar, se necessário. Pergunte se você tiver alguma dúvida ou omiti detalhes importantes.

tl; dr

  • Um sistema de notificação orientado a banco de dados tem implicações negativas para a escalabilidade a longo prazo quando todos os usuários seguem apenas algumas das mesmas centenas de pessoas?
  • Existe uma maneira de tornar as notificações orientadas pelo banco de dados sem a necessidade de uma linha de notificação separada para cada notificação para cada seguidor?
  • Um sistema de notificação totalmente orientado a consultas seria escalável ou teria alguma vantagem além de não gravar nenhum dado no banco de dados?
  • Estou pensando muito cedo? Devo apenas criar algo que funcione por enquanto e podemos nos preocupar em otimizá-lo se isso se tornar um problema, já que o cliente tem um orçamento limitado e ainda não sabemos se o produto final será popular?

Você pode expirar as notificações? Por exemplo, exclua qualquer coisa com mais de 2 semanas de idade. Isso deve equilibrar mais ou menos o tamanho da tabela usada à medida que o site amadurece.
GrandmasterB

Isso não será um problema, eu estava mais preocupado com as implicações de desempenho de bloquear o banco de dados gravando 50.000 entradas na tabela de notificações toda vez que um usuário popular faz uma postagem.
User45623

Eu trabalhei em um projeto com um sistema de notificação semelhante (mas menor). Eu tive um processo em segundo plano que analisou uma fila de novas postagens e lidou com as notificações (que, neste caso, estava realmente inserindo um email em uma segunda fila para envio). Não era em tempo real, mas geralmente lidava com tudo em alguns minutos.
GrandmasterB

Respostas:


10

Portanto, se mil pessoas estiverem seguindo Sally, inseriremos mil linhas na tabela correspondente. Isso é escalável?

Sim, desde que as tabelas do banco de dados sejam indexadas corretamente.

O que acontece se chegarmos ao ponto em que dezenas ou centenas de milhares de usuários estão seguindo Sally e ela está fazendo algumas dezenas de postagens por dia?

Você gerará algumas dezenas ou centenas de milhares de registros de notificação por dia para Sally, supondo que você queira acompanhar todas as notificações permanentemente. A porcentagem de usuários como Sally com esse tipo de tráfego é sempre muito pequena.

Minha idéia original era lidar com tudo com consultas: o número no botão de notificação seria obtido solicitando contagens de linhas no conteúdo postado mais recentemente do que na última vez em que você visitou a tela de notificação, enquanto notificações individuais seriam geradas a partir de consultas mais detalhadas quando você visitou a tela de notificação.

Isso parece desnecessariamente complicado. Se você precisar de estatísticas detalhadas sobre as notificações, basta armazená-las.

Um sistema de notificação orientado a banco de dados tem implicações negativas para a escalabilidade a longo prazo quando todos os usuários seguem apenas algumas das mesmas centenas de pessoas?

É por isso que funciona ... um pequeno número de pessoas sempre gera a grande maioria do tráfego.

Existe uma maneira de tornar as notificações orientadas pelo banco de dados sem a necessidade de uma linha de notificação separada para cada notificação para cada seguidor?

Sim ... Não armazene as notificações; basta enviar os e-mails de notificação, no estilo disparar e esquecer. Ou, armazene as notificações por um determinado período e as descarte. Ou, descarte cada notificação após ter sido lida.

Um sistema de notificação totalmente orientado a consultas seria escalável ou teria alguma vantagem além de não gravar nenhum dado no banco de dados?

Não tenho certeza do que você quer dizer com isso. Se você deseja consultar as notificações, é necessário armazená-las no banco de dados. Caso contrário, não há nada para consultar.

Estou pensando muito cedo?

Converse com alguém que possa ajudá-lo a criar um banco de dados indexado e normalizado adequadamente, com as tabelas corretas. Não vejo razão para que esse banco de dados não possa lidar efetivamente com os cenários que você descreve.

Um exemplo da vida real

Tanto quanto eu sei, o Stack Exchange armazena tudo em perpetuidade, incluindo todas as notificações. Eles usam tecnologia de banco de dados semelhante ao MySql e algumas tecnologias de cache. Embora seu espaço de hardware e armazenamento seja substancial, a quantidade de tráfego que eles recebem é um bom problema.


Uau, você se dirigiu a tudo! Obrigado Robert! O banco de dados está normalizado, mas ainda não vi a indexação. Infelizmente, não posso "falar com alguém que possa me ajudar", pois os termos são rígidos, não posso discutir detalhes específicos do projeto com ninguém, e o cliente chegou ao ponto de não confiar em ninguém mas eu no projeto ... Bem, eu deveria poder fazer alguma pesquisa sobre indexação. Obrigado!
User45623

1
Regras gerais gerais para indexação: toda chave estrangeira deve ser indexada com duplicatas possíveis. Toda chave primária já deve estar indexada. Os campos nos quais você precisará pesquisar ou aplicar uma cláusula WHERE devem ser indexados; esses devem ser poucos.
Robert Harvey

1
Isto está incorreto. Isso não é escalável. Para cada "Sally" você está gerando N linhas onde N é o seu número de usuários. Isso se tornará um problema rapidamente se você tiver um número razoável de usuários. 100 "Sallys" postando 10 vezes para 10.000 usuários é 10 milhões de linhas por dia - não parece muito bom, hein? O que você realmente deseja fazer é inverter isso e criar uma linha por postagem "Sally" e fazer com que todos os usuários que seguem Sally os peguem em vez de sua própria cópia pessoal. É claro que isso vai causar problemas de se precisar de lógica específica do usuário (por exemplo, agregação) ...
Ben

1
... a explicação "evitar uma linha por postagem" aqui é obviamente um homem de palha, pois a maioria dos sistemas exigirá que essas postagens permaneçam por aí. Além disso, você não evita consultas "porque são complicadas", evita-as porque elas causam sobrecarga insustentável à medida que o sistema é dimensionado.
Ben
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.