R
Interview Deckreact · next.js · senior/staff
0·0·122
System Design

System Design — Tracking de Eventos (Visão Geral)

5 camadas: Cliente, Coleta, Streaming, Armazenamento, Consumo. O caso de estudo clássico do Grupo SBF.

Sistema de tracking captura eventos do usuário (cliques, page views, add_to_cart, purchase) no browser e os entrega para análise em tempo real e histórica. Arquitetura em 5 camadas + transversal: (1) Cliente — storefront + Event SDK + dataLayer + batching. (2) Coleta — CDN + Gateway + Collector + Consent LGPD. (3) Streaming — Kafka + Flink + Schema Registry. (4) Armazenamento — Data Lake (S3) + OLAP (ClickHouse) + Warehouse. (5) Consumo — Dashboards + BI + ML + A/B test. Transversal — CI/CD, IaC, Observabilidade, Segurança/LGPD, QA.

Pipeline de Tracking — 5 Camadas
sendBeaconKafkaagregadorawClientestorefrontVTEX IOColetacollector/collectStreamingbroker+procKafka·FlinkHot PathOLAPClickHouseCold PathLake → WarehouseS3·BigQueryConsumodash·BI·ML
Problema
E-commerce precisa medir tudo: conversão, funil, atribuição, recomendação. Sem dado, marketing trabalha no escuro e produto não sabe o que mover. Mas o volume é alto: Centauro tem ~115 eventos/s média e ~1700/s no pico de Black Friday — qualquer pipeline ingênuo cai.
Solução
Pipeline desacoplado: cliente → broker (Kafka) → processor (Flink) → armazenamento (Lake + OLAP). Broker absorve picos, processor enriquece e deduplica, armazenamento separa hot path (OLAP) de cold path (Warehouse). event_id (UUID) garante idempotência em qualquer ponto.
Tip
Comece pela estimativa de bolso: ~15 mi visitantes/mês × 20 eventos/sessão = 300 mi eventos/mês = 115/s média = ~1700/s no pico. Isso dimensiona toda a conversa: que broker, quantas partições, qual OLAP. Estimativa primeiro, arquitetura depois.
// Pipeline completo de tracking — visão de alto nível

// 1. Cliente
window.track('add_to_cart', {
  event_id: crypto.randomUUID(),      // idempotência
  client_timestamp: Date.now(),
  sku: 'NIK-123', price: 299.90,
  session_id: getSession(),
})

// 2. Envio resiliente (sendBeacon + batching)
const batch = queue.flush()
navigator.sendBeacon('/collect', JSON.stringify(batch))

// 3. Collector (Node/Go) — leve, escala horizontal
app.post('/collect', async (req, res) => {
  if (!hasConsent(req)) return res.status(204).end()
  await kafka.produce('events.raw', req.body, {
    partition: hash(req.body.session_id),
  })
  res.status(204).end()  // responde rápido
})

// 4. Stream processor (Flink) — enrich + dedupe + session
events.raw
  .keyBy(e => e.session_id)
  .process(new EnrichEvents())       // geo, device, user
  .filter(e => !seen.contains(e.event_id))  // dedupe
  .window(SessionWindows.withGap(30min))    // sessionização
  .sink(s3Lake, clickHouseOlap)

// 5. Consumo — query no OLAP
SELECT count(*) FROM events
WHERE event_name = 'add_to_cart'
  AND timestamp > now() - INTERVAL 1 HOUR
Q.Qual a primeira pergunta a fazer ao entrevistador?
A.Volume esperado em eventos/segundo no pico (Black Friday). Tudo dimensiona a partir disso. Em seguida: perda de evento é tolerável? Latência aceitável? Quem consome — marketing, BI, ML? Cloud preferida? LGPD?
Q.Qual a ordem de desenho no whiteboard (60 min)?
A.0-10min: requisitos + estimativas. 10-20min: 5 caixas-camada de cima para baixo com setas. 20-40min: aprofundar 2-3 pontos (contrato de evento, broker+processor, modelo OLAP). 40-50min: camada transversal (CI/CD, observabilidade, SLO). 50-60min: trade-offs e gargalos.
Q.Hot path vs cold path: o que é?
A.Hot path: caminho quente em segundos para operação (Kafka → Flink → ClickHouse → Dashboard). Cold path: caminho frio em batch para análise histórica (Lake → Warehouse → BI/ML). Arquitetura Lambda/Kappa. Dois caminhos para necessidades diferentes.
104/122← →