Design clássico · Pleno
Agregador financeiro (Mint)
Projeto de entrevista clássico. Pontos centrais: Pipelines de Dados e Filas de Mensagens.
Resposta curta
Projeto de entrevista clássico. Pontos centrais: Pipelines de Dados e Filas de Mensagens. O exercício clássico pede um agregador financeiro no estilo do Mint: o usuário conecta uma conta financeira, o serviço extrai as transações dessa conta, categoriza cada uma e analisa o gasto mensal por categoria.
01 · CONTEXTO
Muita escrita, pouca leitura
O exercício clássico pede um agregador financeiro no estilo do Mint: o usuário conecta uma conta financeira, o serviço extrai as transações dessa conta, categoriza cada uma e analisa o gasto mensal por categoria. O serviço também recomenda um orçamento, deixa o usuário definir o seu, permite que ele sobrescreva a categoria de uma transação e envia notificações quando o gasto se aproxima do orçamento ou o excede. Alta disponibilidade entra como requisito.
As premissas de escala da fonte descrevem uma base grande e de uso assimétrico: dez milhões de usuários, trinta milhões de contas financeiras e cinco bilhões de transações por mês, contra quinhentos milhões de leituras por mês. A fonte resume isso como uma razão de dez escritas para uma leitura e chama o sistema de intensivo em escrita, porque os usuários transacionam todo dia, mas poucos visitam o site diariamente.
Em média, são 2.000 transações por segundo e 200 leituras por segundo, com cerca de 250 GB de conteúdo novo de transações por mês. A fonte também assume que o tráfego não é distribuído de forma uniforme. Para a coleta de requisitos do caso, esses números e premissas são o ponto de partida da fonte.
02 · INGESTÃO
Da conta conectada à transação categorizada
Ao conectar uma conta, o cliente fala com o servidor web, que encaminha o pedido à API de contas; ela grava a conta recém-informada na tabela de contas do banco SQL. A fonte lembra que adicionar ou remover contas financeiras é relativamente raro.
A extração de transações é disparada em três situações: quando o usuário vincula a conta pela primeira vez, quando atualiza a conta manualmente e, todos os dias de forma automática, para quem esteve ativo nos últimos 30 dias.
O cliente pede a extração; o servidor web encaminha o pedido à API de contas.
Em vez de extrair na hora, a API de contas coloca um job numa fila, porque extrair pode demorar.
O serviço de extração retira o job da fila, busca as transações da conta na instituição financeira e guarda o resultado como arquivos de log brutos no armazenamento de objetos.
Para cada transação, o serviço de extração recorre ao serviço de categorias.
O serviço de orçamento calcula o gasto mensal agregado por categoria e, pelo serviço de notificações, avisa o usuário que se aproxima do orçamento ou o excedeu.
O serviço de extração grava no banco SQL as transações categorizadas e o gasto mensal agregado por categoria.
A fonte prefere fazer a extração de forma assíncrona, com uma fila de mensagens, porque extrair pode demorar, e admite que isso traz complexidade adicional. O aviso de conclusão ao usuário também passa pelo serviço de notificações, que por sua vez usa uma fila para enviar as notificações de forma assíncrona.
03 · CATEGORIAS E ORÇAMENTO
Dicionário, multidão e modelo de orçamento
Para categorizar, a fonte propõe semear um dicionário de vendedor para categoria com os vendedores mais populares. Com 50.000 vendedores e menos de 255 bytes por entrada, ele ocuparia cerca de 12 MB de memória. Para vendedores fora do dicionário, a fonte sugere usar as sobrescritas manuais de categoria que os próprios usuários fazem, numa espécie de crowdsourcing.
Na recomendação de orçamento, a fonte começa com um modelo genérico que distribui valores por categoria conforme faixas de renda. Assim não é preciso guardar os 100 milhões de itens de orçamento das premissas, apenas os que o usuário sobrescreve.
Para o serviço de orçamento, a fonte apresenta duas maneiras de produzir o gasto mensal agregado: consultas SQL sobre a tabela de transações ou, como alternativa, jobs MapReduce sobre os arquivos brutos de transações.
| Abordagem | Como funciona | Ponto destacado pela fonte |
|---|---|---|
| Consultas SQL | Consultas sobre a tabela de transações geram a tabela agregada de gasto mensal | A tabela agregada teria bem menos linhas que o total de transações |
| Jobs MapReduce | Jobs sobre os arquivos brutos de transações geram o gasto mensal agregado por categoria | Analisar os arquivos pode reduzir bastante a carga sobre o banco |
04 · LEITURA
Cache na frente do banco
Para a leitura, a fonte propõe colocar sessões de usuário, estatísticas agregadas por categoria e transações recentes num cache em memória como Redis ou Memcached.
O conteúdo estático pode sair do armazenamento de objetos e ficar em cache na CDN.
O pedido de leitura chega ao servidor web, que o encaminha à API de leitura.
A API de leitura consulta primeiro o cache em memória e, se o conteúdo estiver lá, devolve o que está em cache.
Se o conteúdo não estiver no cache, a API de leitura o busca no banco SQL; as réplicas de leitura devem dar conta dessas falhas de cache, desde que não estejam sobrecarregadas replicando escritas.
Depois de buscar no banco, a API de leitura atualiza o cache com o conteúdo.
Para as 200 leituras médias por segundo, a fonte diz que o tráfego de conteúdo popular deve ser atendido pelo cache e não pelo banco, e que o cache também ajuda com o tráfego irregular e com picos.
05 · ESCRITA
Quando o banco único não basta
As 2.000 escritas médias por segundo, mais ainda nos picos, podem ser difíceis para um único banco SQL de escrita com secundário. A fonte lista padrões adicionais de escala SQL: federação, sharding, desnormalização e ajuste de SQL, e sugere considerar mover parte dos dados para um banco NoSQL.
Para o histórico, a fonte sugere guardar no banco só um mês de transações e deixar o restante num data warehouse ou no armazenamento de objetos, e propõe um banco analítico separado, com um data warehouse como Amazon Redshift ou Google BigQuery. Um armazenamento de objetos como o Amazon S3 comporta com folga os 250 GB de conteúdo novo por mês.
As gravações de transações categorizadas se concentram no banco SQL primário, que a fonte aponta como ponto difícil para as escritas médias.
As réplicas de leitura atendem as falhas de cache, desde que não estejam sobrecarregadas replicando escritas.
O cache em memória atende o conteúdo popular e ajuda com o tráfego irregular e com picos.
Um job em lote analisa os arquivos brutos e gera o gasto mensal agregado por categoria, o que pode reduzir bastante a carga do banco.
06 · FECHAMENTO
O que levar para a entrevista
A fonte avisa para não pular direto ao desenho final a partir do inicial. O caminho que ela indica é medir com teste de carga, perfilar para achar gargalos, tratá-los avaliando alternativas e trocas, e repetir.
Perguntas frequentes
O que é Agregador financeiro (Mint)?
Projeto de entrevista clássico. Pontos centrais: Pipelines de Dados e Filas de Mensagens.
O que o design de Agregador financeiro (Mint) cobre?
Ele está organizado nestas seções: Muita escrita, pouca leitura, Da conta conectada à transação categorizada, Dicionário, multidão e modelo de orçamento, Cache na frente do banco, Quando o banco único não basta e O que levar para a entrevista.
Quanto tempo leva Agregador financeiro (Mint) e qual é o nível?
Leva cerca de 14 minutos para ler e tem nível Pleno.
Agora projete você mesmo
Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.