System Design: métricas em tempo real

Adriano Croco
6 min readMay 18, 2023

Olá!

Este texto faz parte de uma série sobre System Design. Você pode encontrar os desafios anteriores nos links abaixo.

Desafio 0: separando banco de dados
Desafio 1: integração de arquivos
Desafio 2: processamento idempotente de arquivos
Desafio 3: síncrono para assíncrono

Desafio 4: instrumentação de serviços para coleta de métricas de negócio em tempo real

Surpreendentemente, apesar das ferramentas disponíveis, muitas empresas não utilizam ou implementam de forma inadequada a coleta de métricas de negócio em seus serviços. Como você resolveria essa questão?

Solução ingênua

Geralmente, quando falamos de métricas de negócio em tempo real, alguém está querendo acompanhar o número de alguma coisa. Seja a quantidade de pedidos sendo feitos por hora, o volume de receita financeira, o percentual de fraude, a quantidade de vendas por loja e indicadores de negócio similares.

O jeito mais simples de fazer isso é descobrir em quais tabelas os dados estão e simplesmente ficar rodando stored procedures em produção que sumarizam esses dados e mandam por e-mail para quem pediu. Não é tempo real, mas deve ser o suficiente, certo?

Diagrama macro dessa solução

Essa ideia é ruim por muitos motivos. O primeiro é a questão de um job qualquer ficar rodando com mecanismos temporais. O grande problema desse tipo de solução é que, caso o tempo de processamento aumente com o tempo (e é quase inevitável que isso aconteça, dado o aumento no volume de dados), há a possibilidade do processamento começar a invadir a janela de processamento do próximo job, gerando um problema ainda maior. Além disso, sistemas que gerem relatórios dessa natureza não devem obter esses dados a partir de um database transacional. Os dados sempre devem vir de outra fonte que foi otimizada para relatórios (mais detalhes adiante). E por fim, mandar relatórios por e-mail em um tempo tão curto é um desperdício de tempo e espaço da caixa de entrada do solicitante (imagine receber um e-mail a cada 5 minutos, isso dá 96 e-mails por dia, somente considerando horário comercial).

A primeira ação que é passível de ser feita para melhorar essa solução é resolver o problema da fonte de dados. Afinal, toda essa estrutura está do jeito que está porque os dados relevantes estão no banco de dados, certo?

E se jogássemos esses dados para outro lugar?

O que importa para uma análise em tempo real é saber quando algo aconteceu. Logo, uma forma de se enxergar esse tipo de situação é modelar esse problema a partir de uma abordagem de eventos. Afinal, um evento é simplesmente uma representação em forma de dados de algo que ocorreu no passado. Eu sei que pode parecer óbvio, mas em se tratando de eventos em computação, só podemos lidar com o passado. O presente e o futuro não existem para computadores. De certa forma, eu acho isso filosoficamente fascinante. Pois, em última instância, o tempo real em computadores é impossível (caso você interprete o termo tempo real literalmente).

O máximo que conseguimos fazer é, após um período bem curto de tempo, sumarizar os eventos em algum lugar. Mesmo que você use algum mecanismo otimizado de visualização dos dados, ainda sim, há uma espaço de tempo entre o que aconteceu e o dado aparecer na tela (nem que seja alguns milissegundos). Que é o máximo que é possível atingir do ponto de vista conceitual. Para nosso senso de percepção parece imediato, mas tecnicamente não é.

Mas enfim, divago.

A forma mais simples de evoluir com a solução é, ao mesmo tempo em que escrevemos dados no repositório, a aplicação irá gerar eventos sobre o que aconteceu. Justamente esses eventos que serão considerados os dados corretos a serem analisados em tempo real. Ou seja, a fonte única da verdade (single source of truth) para os dados em tempo real se tornará os eventos a partir de agora. Essa é uma boa prática em modelagem de sistemas de uma maneira geral. Afinal, imagine tentar afirmar com certeza o que aconteceu em um sistema olhando duas fontes da verdade distintas?

Com essa alteração, o desenho da solução se torna o abaixo:

Estrutura usando eventos

Para melhorarmos ainda mais, a solução precisa usar os eventos de uma forma mais inteligente. Se temos uma base confiável de eventos do passado, com todos os seus metadados correspondentes, por que não simplesmente consultá-la gerando queries manualmente?

Essa estrutura resolve uma parte do problema, mas ainda permanece o problema temporal dos jobs e do excesso de envio de e-mails.

Com essa estrutura funcionando, é possível executar as queries direto na base de eventos e disponibilizar em uma interface qualquer as métricas, atualizadas a cada cinco minutos ou algo similar. Porém, aqui entra outro ponto: a forma como as métricas funcionam costumam mudar ao longo do tempo, caso qualquer alteração no relatório seja necessária, você terá toda uma estrutura feita em código a ser alterada.

É possível fazer uma ferramenta caseira que resolva todos esses problemas, porém, como não é necessário construir algo que já foi construído, este será um texto que irei recomendar ferramentas prontas ao invés de discutir a arquitetura em si.

APM

A sigla APM significa Application Performance Management. No mundo real, é possível encontrar inúmeras ferramentas pagas que fazem isso, como o Dynatrace, New Relic e o Datadog. Eu já usei algumas delas, mas no final das contas, o que vai influenciar qual será usada geralmente é o custo mesmo.

Esse tipo de ferramenta tem algumas vantagens, como permitir uma visibilidade melhor do uso de recursos das aplicações (como CPU, RAM e Disco) e também monitora quantidade de requests, latência e indicadores relacionados. Para gestão de incidentes e melhora de observabilidade, é o ideal.

Com uma ferramenta dessas rodando, é possível obter dashboards como o abaixo:

Exemplo de uma dashboard com indicadores de um sistema de pagamentos

Como esse tipo de ferramenta já possui uma estrutura interna de processamento e indexação de eventos de forma eficiente, além de dashboards simples de construir, acaba sendo um desperdício de energia construir algo assim do zero. A tecnologia viabilizadora desse tipo de ferramenta é o uso correto de banco de dados de séries temporais (Time Series Databases, ou TSDs). Que são sistemas feitos para processamento de pontos de dados que são coletados em intervalos regulares ao longo do tempo, ou seja, um outro termo para se referir a eventos.

Existem alternativas open source que valem a pena ser mencionadas também, como o Grafana (que suporta dashboards e permite customizar queries) e o Prometheus (que age como um TSD processador de eventos). A grande diferença dessa estrutura para as outras ferramentas mencionadas é que o gerenciamento das ferramentas, como a gestão de acessos e clusters é feito via um time de infraestrutura interno. Tirando isso, é uma solução tão boa quanto qualquer outra. Nesse caso, a aplicação envia dados para o Prometheus e ele é usado como fonte de dados para o Grafana. Na prática, o que o Datadog e o NewRelic entregam com uma única solução cloud, você pode fazer a mesma coisa manualmente usando Grafana e Prometheus.

Abaixo segue um exemplo de uma dashboard de métricas de negócio feita no Grafana:

Exemplo de uma página de métricas no Grafana

Independente do tipo de ferramenta (seja paga ou open source), temos o seguinte desenho final:

Solução escrevendo no banco de dados e no APM ao mesmo tempo

Com essa estrutura, basta configurar as métricas agrupando eventos pela própria ferramenta de APM ou direto no Grafana. Com isso, as buscas são efetuadas de forma mais eficiente e não oneram as bases transacionais. Com isso, a percepção de indicadores de negócios sendo exibidos em tempo real é atingida com sucesso.

Se você encontrar algum erro ou informação incompleta neste texto, me mande uma mensagem que eu ajustarei.

Obrigado pela leitura!

Até!

Você gostou do conteúdo e gostaria de fazer mentoria comigo? Clique aqui e descubra como.

--

--