
Uber
Como a Uber construiu uma plataforma de dados em tempo real pra casar passageiros e motoristas em 10.000 cidades.
Números que importam
Stack técnica
A arquitetura em um dashboard interativo
A ideia é essa: aprender lendo o diagrama. Cada caixa e cada seta conta uma parte da história — clique pra abrir.
Cor indica o papel: cliente, streaming, storage, compute, ML, serving. Clique em qualquer caixa pra ver o que é, por que é usada e como funciona ali.
OpcionalLer o deep dive completo em textoAs mesmas ideias do diagrama, com mais contexto — recomendado depois de explorar as etapas.
O problema: 30M de corridas por dia, e cada uma é uma decisão em tempo real
Uber não é um problema de "big data" — é um problema de big real-time. Quando você toca em "solicitar", a plataforma tem que:
- Achar motoristas próximos (query geo no estado ao vivo dos motoristas)
- Calcular uma tarifa (modelo de surge baseado nos últimos N minutos de oferta/demanda)
- Rotear a viagem (ETA a partir do trânsito ao vivo)
- Pontuar fraude (em <100ms)
- Atualizar dezenas de sistemas downstream (contabilidade, ganhos do motorista, métricas de marketplace)
Tudo isso em cerca de um segundo. E depois o mesmo evento tem que cair num lakehouse pro re-treino do modelo amanhã. Esse requisito duplo — sub-segundo E analítico — é o que moldou toda escolha da plataforma.
Kafka é o sistema nervoso
Todo evento relevante na Uber flui pelo Kafka. A Uber roda um dos maiores deployments de Kafka do mundo — trilhões de mensagens por dia em milhares de tópicos. Duas decisões de design importam:
- Tópicos chaveados por entidade, não por serviço.
trip_eventschaveado portrip_uuidsignifica que todo consumer vê atualizações ordenadas por viagem. - Producers escrevem uma vez; Kafka Connect / uReplicator distribui pra regiões e sinks downstream. Producers não sabem nem se importam pra onde o dado vai.
A Uber também open-sourceou o uReplicator (depois substituído por melhorias do MirrorMaker 2) especificamente pra resolver replicação cross-datacenter na escala deles — o tooling nativo do Kafka não bastava.
Apache Pinot: OLAP sub-segundo em dados ao vivo
Warehouses tradicionais respondem queries analíticas em segundos a minutos. A Uber precisava de milissegundos — pra alimentar dashboards de surge, detecção de fraude, calibração de ETA. Eles co-criaram o Apache Pinot pra preencher essa lacuna.
Pinot é um store OLAP colunar que ingere direto do Kafka e responde queries slice-and-dice em <100ms a 100k+ QPS. Um exemplo concreto:
-- "Quantas viagens completas por cidade nos últimos 5min?"
-- Sustenta o modelo de surge. Roda a cada poucos segundos.
SELECT city_id, COUNT(*) AS trips
FROM trip_events
WHERE event_type = 'TRIP_COMPLETED'
AND event_time >= ago('PT5M')
GROUP BY city_id;
Mesmo SQL que você escreveria em Postgres. Mas Pinot pré-materializa os segments, mantém dado quente em memória e devolve em 20-50ms. É a diferença entre "surge reagindo à realidade" e "surge reagindo ao que rolou há 20 minutos".
Apache Hudi: o lakehouse antes de lakehouses serem chamados assim
A Uber escreveu o Apache Hudi em 2016, três anos antes de "lakehouse" virar termo de marketing. O problema que resolveram: como fazer upserts em HDFS/S3? Uma viagem pode atualizar dezenas de vezes (aceita → iniciada → completada → ajustada → estornada), e reescrever a partição inteira toda vez era insustentável.
Hudi introduziu dois tipos de tabela que hoje são vocabulário padrão:
- Copy-on-Write (CoW): reescreve arquivos na atualização. Leitura mais simples, escrita mais cara. Boa pra tabelas com muita análise.
- Merge-on-Read (MoR): escreve deltas; leitores fazem merge on-the-fly ou via job de compactação. Escrita mais rápida, leitura mais cara. Boa pra tabelas de alta velocidade tipo estado de viagem.
Todo lakehouse moderno (Iceberg, Delta) tem alguma versão disso hoje. Hudi entregou primeiro porque a Uber precisava.
Michelangelo: ML como produto, não como projeto
Michelangelo é a plataforma de ML interna da Uber. O pitch pros times internos: entregue suas features e um ponteiro pros dados de treino, a gente cuida do resto — treino, deploy, monitoring, re-treino. Os mesmos trilhos sustentam detecção de fraude, previsão de ETA, score de motorista, matching.
A ideia arquitetural chave é o feature store como cidadão de primeira classe. Features definidas uma vez (em tabelas Hive/Hudi) e servidas tanto offline (pro treino) quanto online (via um store de baixa latência como Cassandra). Mesmo padrão que a Netflix usa — e toda org séria de ML converge pra isso.
O que você pode de fato roubar desse design
- OLAP em tempo real é uma camada própria. Se seus dashboards precisam de frescor sub-segundo, não tente fazer o Snowflake resolver. Olhe pra Pinot, Druid ou ClickHouse. Eles existem exatamente pra isso.
- Upserts no lake não são negociáveis. No momento em que seu dado tem qualquer correção, ajuste ou dimensão que muda devagar, você precisa de um formato de tabela com semântica de upsert. Hudi, Iceberg ou Delta — escolha um, mas escolha.
- Tópicos Kafka são entidades, não serviços. Um tópico por serviço cria um grafo de pipelines ponto-a-ponto. Um tópico por entidade (user, order, session, trip) cria uma interface estável que todo consumer compartilha.
- A plataforma de ML É a estratégia de ML. Se todo time constrói seu próprio training loop, você tem cinco plataformas de ML e nenhum aprendizado. Michelangelo (ou algo parecido) é o multiplicador.
Fontes e leituras curadas
As fontes públicas por trás desta análise, com nosso comentário sobre por que valem seu tempo.
Nossa leitura: Filtre pelas tags 'data' e 'infrastructure'.
Nossa leitura: O melhor post de visão geral se você só puder ler um.
Nossa leitura: Como e por que o Pinot venceu internamente contra Druid e Elasticsearch.
Nossa leitura: A história de origem e evolução do Hudi.
Nossa leitura: Antigo mas fundacional. O conceito de feature store como produto na Uber.
Aprenda o que faz isso funcionar
As aulas do DataForge que cobrem as peças dessa arquitetura.