Arquitetura real · Sênior
Banco com banco de dados imutável: Datomic, Clojure e Kafka no núcleo do Nubank
O domínio de auditoria justifica cada escolha: replay com reset de offset, consultas point-in-time, a "diplomat architecture" e a padronização da stack ao passar de 50 para mais de 600 engenheiros.
Resposta curta
O domínio de auditoria justifica cada escolha: replay com reset de offset, consultas point-in-time, a "diplomat architecture" e a padronização da stack ao passar de 50 para mais de 600 engenheiros. O Nubank partiu de uma premissa do domínio financeiro: para um banco, é preciso ter todo o histórico, a trilha de auditoria completa de tudo o que se faz…
01 · CONTEXTO
Auditoria como requisito de partida
O Nubank partiu de uma premissa do domínio financeiro: para um banco, é preciso ter todo o histórico, a trilha de auditoria completa de tudo o que se faz. A primeira escolha técnica, o banco de dados, veio daí.
O Datomic é descrito por Cavalcanti, do Nubank, como um banco de nicho, um livro imutável de fatos: cada atualização preserva o histórico e os valores anteriores não se perdem. Em vez de guardar apenas o dado, ele guarda as mudanças sobre o dado, como um repositório Git. Na hora de escolher o banco, é esse comportamento que o domínio pediu.
O banco também permite consultar os dados em qualquer ponto no tempo, o que ajuda tanto na auditoria quanto na depuração posterior.
02 · A STACK DE PARTIDA
Datomic, Clojure, Kafka e AWS
O Clojure veio por causa do Datomic, que é construído em Clojure; o time já ia, de qualquer forma, para uma linguagem funcional. Para a mensageria, a escolha foi o Kafka, que ganhava tração em 2013 e mantém um log de mensagens que pode ser reproduzido. A nuvem escolhida foi a AWS, com o DynamoDB como banco de apoio do Datomic.
O cliente chama um serviço de domínio; a linguagem principal escolhida foi o Clojure.
O serviço grava no Datomic, que guarda as mudanças sobre os dados como um repositório Git, e não apenas o valor atual.
O Datomic usa o DynamoDB como banco de apoio.
Na leitura, o serviço pode consultar o banco em qualquer ponto no tempo, o que serve à auditoria e à depuração.
| Escolha | O que a fonte aponta |
|---|---|
| Datomic | Livro imutável de fatos; cada atualização preserva o histórico |
| Clojure | Linguagem funcional na JVM, com imutabilidade por padrão |
| Kafka | Log persistente de mensagens, com TTL, e offsets que podem ser resetados |
| Dívida | Tecnologias de nicho e pouco consolidadas; difícil achar gente com experiência |
03 · EVENTOS
Kafka: o log que dá para reler
Cavalcanti descreve o Kafka como um log persistente de mensagens, com TTL: não é para sempre, mas durante um período dá para inspecionar tudo o que foi produzido. Há também a possibilidade de resetar offsets e reprocessar mensagens antigas quando necessário, algo que o time precisou fazer algumas vezes no começo.
Um serviço publica mensagens no Kafka, a tecnologia de mensageria escolhida.
O log é persistente e tem TTL: não dura para sempre, mas durante um período dá para inspecionar o que foi produzido.
No diagrama, o consumidor lê do log e grava o resultado no próprio banco.
Resetando o offset, as mensagens antigas podem ser reprocessadas quando necessário.
04 · CÓDIGO E INFRAESTRUTURA
Diplomat architecture e imutabilidade
O Nubank adotou microsserviços desde o começo, porque o domínio financeiro é muito complexo e conter essa complexidade em serviços pequenos era importante para o time.
Para organizar o código de cada serviço, o time se inspirou na arquitetura hexagonal, mas deu à variante um nome próprio, diplomat architecture, para não confundir com a ideia original. Na descrição de Cavalcanti, a camada de controle trata os efeitos colaterais e outra camada guarda a lógica de negócio, feita de funções puras que recebem mapas e devolvem mapas.
| Aspecto | Hexagonal, segundo Cavalcanti | Diplomat architecture do Nubank |
|---|---|---|
| Onde a ideia vai | A definição de Cockburn para no controller; depois dele já é lógica de negócio | Separa a lógica de negócio pura da lógica impura, com efeitos colaterais |
| Origem do nome | Portas e adaptadores | Nome próprio, inspirado em portas e adaptadores, com viés funcional |
A imutabilidade vale também fora do código. Cavalcanti diz que a maior parte do estado mutável fica no banco de dados e que, no Datomic, quem pede o banco recebe um valor: o tempo para, e nenhuma nova transação aparece naquele valor. A infraestrutura segue a mesma ideia: em vez de alterar uma máquina em execução, cria-se uma nova com a nova configuração ou o novo código.
05 · DADOS E CONCILIAÇÃO
Onde a conferência entra
Com serviços que têm cada um o seu banco, e shards com cópias desses bancos, os dados ficam em dois cortes: por serviço e por shard. Foi preciso um sistema agregador que reunisse os dados de todos os serviços em todos os shards.
Cada serviço tem o seu próprio banco, e há cópias desses bancos em shards.
O ETL extrai os dados dos bancos dos serviços em todos os shards.
A saída do ETL vai para um data warehouse.
O mesmo ETL é usado para checar a consistência entre os sistemas, já que transações distribuídas que falham viram um problema grande.
Segundo a palestra, com esse volume de dados e uma arquitetura distribuída, transações distribuídas que falham viram um problema grande, e o ETL também é usado para conferir a consistência entre os sistemas.
A escolha de não usar Kafka Streams para o ETL tem uma razão explicada por Cavalcanti: quando precisaram de ETL, o Kafka Streams não estava estável nem lançado.
06 · ESCALA DA ORGANIZAÇÃO
Canonicidade: de 50 a mais de 600 engenheiros
Quando perguntam pela stack do Nubank, a resposta é curta: Clojure nos serviços de produção, Kafka na comunicação assíncrona, Datomic para dados de negócio de alto valor, Scala no ambiente analítico e Flutter no app.
Depois de sete anos construindo produtos, com mais de 600 engenheiros, o blog Building Nubank pergunta se preferir menos variância nas tecnologias resulta numa organização de engenharia mais eficiente. Os autores dizem que o alinhamento era mais fácil, mas não fácil, com 50 engenheiros, e que com 600 é diferente e mais complicado.
Na prática, uma equipe deve conseguir codar, testar e fazer deploy sem depender de outra equipe. Quando alguém precisa trabalhar fora do seu domínio, é muito provável que as duas equipes usem Clojure, Kafka e Datomic, e há bibliotecas padrão para falar com Datomic, DynamoDB, Kafka e HTTP.
A padronização admite exceções: o primeiro ETL foi feito em Spark com Scala, e os serviços de aprendizado de máquina, em Python.
Perguntas frequentes
O que é Banco com banco de dados imutável: Datomic, Clojure e Kafka no núcleo do Nubank?
O domínio de auditoria justifica cada escolha: replay com reset de offset, consultas point-in-time, a "diplomat architecture" e a padronização da stack ao passar de 50 para mais de 600 engenheiros.
O que o design de Banco com banco de dados imutável: Datomic, Clojure e Kafka no núcleo do Nubank cobre?
Ele está organizado nestas seções: Auditoria como requisito de partida, Datomic, Clojure, Kafka e AWS, Kafka: o log que dá para reler, Diplomat architecture e imutabilidade, Onde a conferência entra e Canonicidade: de 50 a mais de 600 engenheiros.
Quanto tempo leva Banco com banco de dados imutável: Datomic, Clojure e Kafka no núcleo do Nubank e qual é o nível?
Leva cerca de 17 minutos para ler e tem nível Sênior.
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.