Construindo um pipeline de análise de fraude em tempo real
Passo a passo da arquitetura: ingerindo 50 mil eventos/segundo, enriquecendo com Smart Signals e pontuando risco em menos de 10ms usando nosso motor de streaming.
Processar 50.000 eventos de impressão digital por segundo, enriquecer cada um com Smart Signals e retornar uma pontuação de risco em menos de 10 milissegundos exige uma arquitetura de streaming cuidadosamente projetada. Este artigo percorre nosso pipeline da ingestão à decisão.
Camada de ingestão
Os eventos chegam como requisições HTTPS POST a partir do nosso agente JavaScript rodando nos navegadores dos visitantes. Cada evento contém a carga útil criptografada de sinais — tipicamente 8-12KB de dados comprimidos cobrindo mais de 300 sinais do navegador. Nossos servidores de borda encerram o TLS, validam a assinatura da requisição e encaminham a carga útil ao pipeline de processamento.
Usamos uma implantação multirregião em que os servidores de borda ficam colocalizados com os nós de CDN dos nossos clientes. Isso mantém a viagem de ida e volta da rede abaixo de 20ms para 95% das requisições globalmente. Os servidores de borda são serviços Go sem estado rodando atrás de um balanceador de carga, escalando horizontalmente com base no volume de requisições.
Extração de sinais
O primeiro estágio de processamento descriptografa e faz o parse da carga útil de sinais. Cada sinal é extraído, validado e tipado. Os hashes de canvas são verificados contra valores conhecidamente impossíveis (que indicam bloqueio ou falsificação de canvas). Os parâmetros de WebGL são validados cruzadamente quanto à consistência. As propriedades do Navigator são checadas contra combinações válidas conhecidas.
Este estágio também realiza a normalização de sinais. As strings de user agent são analisadas em componentes estruturados (navegador, versão, SO, dispositivo). As dimensões da tela são normalizadas para levar em conta o escalonamento de DPI.
Enriquecimento com Smart Signals
Os sinais extraídos são então enriquecidos com a análise dos Smart Signals — nossa camada de inteligência do lado do servidor. Isso inclui classificação de rede (resolvendo endereços de VPN, proxy, Tor e datacenter a partir de bancos de dados comerciais de inteligência de IP), detecção de adulteração do navegador (identificando inconsistências que indicam falsificação de sinais), análise de velocidade (contando eventos, endereços distintos e localizações em janelas recentes) e pontuação comportamental (comparando a dinâmica de ponteiro, teclado e rolagem com linhas de base humanas).
Os planos Enterprise adicionam a detecção de máquina virtual a esse mesmo estágio. Ela lê as strings de renderer e de vendor do WebGL em busca de assinaturas de VMware, VirtualBox, Parallels, QEMU e Hyper-V, e depois as confronta com resoluções de tela, contagens de núcleos e tamanhos de memória típicos de VMs — nenhum marcador isolado decide, a combinação decide.
Cada smart signal é computado de forma independente e produz tanto um resultado quanto uma pontuação de confiança. O estágio de enriquecimento adiciona mais de 35 campos computados no servidor a cada evento, fornecendo uma avaliação de ameaças que vai além do que a coleta do lado do cliente sozinha pode alcançar.
Motor de pontuação de risco
O evento enriquecido é passado ao nosso motor de pontuação de risco — um modelo de árvore de decisão com gradient boosting treinado em milhões de eventos rotulados. O modelo considera todos os mais de 300 sinais brutos, os mais de 35 smart signals computados no servidor e vários recursos derivados: métricas de velocidade (quantos eventos deste dispositivo nos últimos 5 minutos, 1 hora e 24 horas), padrões de comportamento histórico e pontuações de reputação de rede.
O modelo produz uma pontuação de risco entre 0 e 100, junto com os principais fatores contribuintes. Uma pontuação de 85, por exemplo, pode vir acompanhada de fatores como "VPN detectada", "modo anônimo" e "alta velocidade — 47 eventos em 5 minutos". Essa explicabilidade é fundamental para os analistas de fraude que precisam entender por que um evento em particular foi sinalizado.
Camada de armazenamento e consulta
Todos os eventos são persistidos no ClickHouse — um banco de dados colunar otimizado para consultas analíticas sobre grandes conjuntos de dados. O ClickHouse lida com nosso volume de escrita (50 mil eventos/segundo) sem esforço, e seu armazenamento colunar viabiliza consultas analíticas em menos de um segundo sobre bilhões de linhas.
Usamos uma estratégia de retenção em múltiplas camadas. Dados quentes (últimos 7 dias) ficam em SSDs NVMe para resposta de consulta em menos de 100ms. Dados mornos (7-90 dias) ficam em SSDs padrão. Dados frios (90+ dias) são comprimidos e movidos para o armazenamento de objetos, consultáveis, mas com maior latência.
Kafka como espinha dorsal
O Apache Kafka amarra o pipeline. Cada estágio lê de e escreve em tópicos do Kafka. A camada de ingestão escreve eventos brutos. O estágio de extração de sinais lê eventos brutos e escreve eventos extraídos. O estágio de enriquecimento com Smart Signals lê eventos extraídos e escreve eventos enriquecidos. O motor de pontuação de risco lê eventos enriquecidos e escreve eventos pontuados.
Essa arquitetura oferece várias vantagens: os estágios podem ser escalados de forma independente, falhas em um estágio não afetam os outros, e podemos reprocessar eventos por qualquer estágio para depuração ou reprocessamento. Os consumer groups do Kafka viabilizam o processamento paralelo dentro de cada estágio, e sua semântica exactly-once garante que nenhum evento seja processado duas vezes ou perdido.
Orçamento de latência
Nossa meta de latência de ponta a ponta é de 10ms, do momento em que a carga útil de sinais enriquecidos chega ao pipeline de processamento até o momento em que a pontuação de risco é retornada. Veja como o orçamento se distribui: a extração de sinais leva 1-2ms, o enriquecimento com Smart Signals leva 3-4ms, a pontuação de risco leva 2-3ms, e a serialização e resposta levam 1-2ms. O salto do Kafka entre estágios adiciona menos de 1ms em nossa implantação colocalizada.
Cumprir esse orçamento de forma consistente a 50 mil eventos/segundo exige otimização cuidadosa em cada estágio. Usamos pools de memória pré-alocados, serialização zero-copy e escritas em lote no ClickHouse. O modelo de pontuação de risco é compilado para código nativo usando o ONNX Runtime, eliminando a sobrecarga do interpretador Python.
Mark passou duas semanas perfilando o pipeline antes de encontrar o gargalo em nossa camada de consulta distribuída — um único mutex estava serializando as consultas em todas as goroutines. Após mudar para um design de lock fragmentado, o p99 caiu de 48ms para 9ms. Às vezes a correção é constrangedoramente simples, uma vez que você a encontra.