Em 2018, criei um software que impactou 141 milhões de usuários com pico de quase 3 milhões em 24 horas, conforme o Google Analyics abaixo. Clique na imagem para expandi-la.
1. O problema
Esse negócio era composto por redatores, sites de conteúdo, usuários dos sites, um software para gestão do negócio e usuários do software.
Os redatores criavam matérias nos sites de conteúdo. Os usuários do software criavam uma conta no software e geravam URLs de qualquer matéria de um dos sites de conteúdo para divulgarem em suas redes sociais. A partir disso, acessavam o software para saber quantas pessoas haviam clicados em suas URLs. Essa era a principal funcionalidade do software.
Com o aumento do número de usuários do software, o número de usuários dos sites (pessoas que clicavam nas URLs) aumentou e a solução que eu havia criado passou a não funcionar corretamente. Clique na imagem do Google Analytics acima para expandí-la e observe esse aumento rápido no início de Setembro de 2018.
Dado ao alto volume de requisições, cujo o pico de usuários simultâneos passou de 1 mil para 5-10 mil, todas as requisições passaram a não ser mais reconhecidas pelo software.
A solução foi incluir um servidor somente para dados e o uso de dados temporários em memória. Isso é descrito no item à seguir.
2. A solução
A arquitetura da solução está na imagem abaixo. Usei uma formatação livre.
À seguir, a descrição de cada numeração da imagem.
1. Usuário do site acesso o conteúdo
Uma pessoa estava navegando pelo Facebook, por exemplo, vê um post sobre um conteúdo e clica no link desse post.
O Facebook redireciona essa pessoa para um site de conteúdo e ela torna-se usuário do site.
2. Site envia dados ao Google Analytics
Em todo carregamento de página de um site (pageview), o site notifica o Google Analytics sobre tal pageview.
3. Site envia dados ao servidor de dados
Em todo carregamento de página de um site (pageview), o site notifica o servidor de dados sobre tal pageview.
4. Servidor de dados armazena dados em memória
Toda notificação, o servidor de dados armazena os dados da requisição em memória usando Redis.
5. Servidor de dados armazena dados em disco
A cada 30 segundos, os dados em memória armazenados no Redis era obtido e armazenado em disco no MySQL e os dados em memória apagados.
6. Servidor de dados envia dados para o servidor do software
A cada 1 minuto, os dados em disco no servidor de dados eram enviados para o servidor do software.
7. Servidor da software armazena dados em disco
Com os dados recebidos, o software armazenava os dados em disco.
8. Servidor do software obtém dados do Google Analytics
O software obtinha dados complementares no Google Analytics.
9. Usuário do software obtém dados do servidor do software
Os usuários do software acessavam o software para visualizar quantos cliques existiam em seus links.
Com a solução funcionando com o servidor de dados usando dados em memória, o software conseguia atualizar os dados consistentes a cada 1 minuto, algo que não acontecia na solução anterior (sem o servidor dados e sem dados em memória).
3. A conclusão
Negócios que possuem aquisição de usuários pela internet estão sujeitos a uma escala inesperada de novos usuários.
A primeira solução que eu criei não estava preparada para tal escala. A adição do servidor de dados em memória resolveu o problema.
Como cada usuário de um site pode realizar mais de um pageview, ao final, o servidor de dados com dados em memória recebeu 366 milhões de requisições, conforme imagem abaixo.
O pico de acesso em 24 horas foi mais de 7 milhões. Simultâneos foi por volta de 25 mil usuários, embora eu não tenha essa imagem para mostrar aqui.
Em todos esses dias, o servidor de dados conseguiu receber, armazenar e fornecer de forma consistente os dados de todas as pageviews.
A decisão ruim que tomei na nova solução foi instalar o Apache no servidor de dados, ao invés do Nginx. O Apache consome muito mais memória RAM do que o Nginx e o custo do servidor foi mais caro.
De todo o modo, o Apache tratou com sucesso todas as requisições, os dados ficaram consistentes e o problema foi resolvido.