Construir un pipeline de analítica de fraude en tiempo real
Recorrido por la arquitectura: ingerir 50K eventos/segundo, enriquecer con smart signals y puntuar el riesgo en menos de 10ms usando nuestro motor de streaming.
Procesar 50,000 eventos de huella digital por segundo, enriquecer cada uno con smart signals y devolver una puntuación de riesgo en menos de 10 milisegundos requiere una arquitectura de streaming cuidadosamente diseñada. Este artículo recorre nuestro pipeline desde la ingesta hasta la decisión.
Capa de ingesta
Los eventos llegan como solicitudes HTTPS POST desde nuestro agente JavaScript ejecutándose en los navegadores de los visitantes. Cada evento contiene el payload de señales cifrado —normalmente 8-12KB de datos comprimidos que cubren más de 130 señales de navegador—. Nuestros servidores edge terminan el TLS, validan la firma de la solicitud y reenvían el payload al pipeline de procesamiento.
Usamos un despliegue multirregión en el que los servidores edge están colocados junto a los nodos CDN de nuestros clientes. Esto mantiene la ida y vuelta de red por debajo de 20ms para el 95% de las solicitudes a nivel global. Los servidores edge son servicios Go sin estado que se ejecutan detrás de un balanceador de carga, escalando horizontalmente según el volumen de solicitudes.
Extracción de señales
La primera etapa de procesamiento descifra y parsea el payload de señales. Cada señal se extrae, valida y tipa. Los hashes de canvas se verifican frente a valores imposibles conocidos (que indican bloqueo o suplantación de canvas). Los parámetros de WebGL se validan de forma cruzada para comprobar su consistencia. Las propiedades del navigator se contrastan con combinaciones válidas conocidas.
Esta etapa también realiza la normalización de señales. Las cadenas de user agent se parsean en componentes estructurados (navegador, versión, sistema operativo, dispositivo). Las dimensiones de pantalla se normalizan para tener en cuenta el escalado de DPI. Los desfases de zona horaria se validan frente a los datos de geolocalización por IP.
Enriquecimiento con Smart Signals
Las señales extraídas se enriquecen luego con el análisis de Smart Signals, nuestra capa de inteligencia del lado del servidor. Esto incluye detección de incógnito (comparando los patrones de señales frente a firmas conocidas de navegación privada), detección de VPN (cruzando los datos de IP con las señales de zona horaria y configuración regional), detección de manipulación del navegador (identificando inconsistencias que indican suplantación de señales) y detección de máquina virtual (reconociendo perfiles de hardware asociados a VMware, VirtualBox y VM en la nube).
Cada smart signal se calcula de forma independiente y produce tanto un resultado booleano como una puntuación de confianza. La etapa de enriquecimiento añade 24 señales adicionales a cada evento, proporcionando una evaluación de amenazas exhaustiva que va más allá de lo que la recopilación en el cliente por sí sola puede lograr.
Motor de puntuación de riesgo
El evento enriquecido pasa a nuestro motor de puntuación de riesgo, un modelo de árbol de decisión con gradient boosting entrenado con millones de eventos etiquetados. El modelo considera las más de 130 señales sin procesar, las 24 smart signals y varias features derivadas: métricas de velocidad (cuántos eventos de este dispositivo en los últimos 5 minutos, 1 hora y 24 horas), patrones de comportamiento histórico y puntuaciones de reputación de red.
El modelo produce una puntuación de riesgo entre 0 y 100, junto con los principales factores contribuyentes. Una puntuación de 85, por ejemplo, podría ir acompañada de factores como "VPN detectada", "modo incógnito" y "alta velocidad: 47 eventos en 5 minutos". Esta explicabilidad es crítica para los analistas de fraude que necesitan entender por qué se marcó un evento concreto.
Capa de almacenamiento y consulta
Todos los eventos se persisten en ClickHouse, una base de datos columnar optimizada para consultas analíticas sobre grandes conjuntos de datos. ClickHouse maneja nuestro volumen de escritura (50K eventos/segundo) sin despeinarse, y su almacenamiento columnar permite consultas analíticas de menos de un segundo sobre miles de millones de filas.
Usamos una estrategia de retención multinivel. Los datos calientes (últimos 7 días) se almacenan en SSD NVMe para respuestas de consulta de menos de 100ms. Los datos templados (7-90 días) están en SSD estándar. Los datos fríos (más de 90 días) se comprimen y se mueven a almacenamiento de objetos, consultables pero con mayor latencia.
Kafka como columna vertebral
Apache Kafka une el pipeline. Cada etapa lee de topics de Kafka y escribe en ellos. La capa de ingesta escribe eventos sin procesar. La etapa de extracción de señales lee eventos sin procesar y escribe eventos extraídos. La etapa de enriquecimiento con Smart Signals lee eventos extraídos y escribe eventos enriquecidos. El motor de puntuación de riesgo lee eventos enriquecidos y escribe eventos puntuados.
Esta arquitectura ofrece varias ventajas: las etapas se pueden escalar de forma independiente, los fallos en una etapa no afectan a las demás, y podemos reproducir eventos a través de cualquier etapa para depuración o reprocesamiento. Los consumer groups de Kafka permiten el procesamiento en paralelo dentro de cada etapa, y su semántica exactly-once garantiza que ningún evento se procese dos veces ni se pierda.
Presupuesto de latencia
Nuestro objetivo de latencia de extremo a extremo es de 10ms desde el momento en que el payload de señales enriquecido llega al pipeline de procesamiento hasta el momento en que se devuelve la puntuación de riesgo. Así se desglosa el presupuesto: la extracción de señales tarda 1-2ms, el enriquecimiento con Smart Signals tarda 3-4ms, la puntuación de riesgo tarda 2-3ms, y la serialización y la respuesta tardan 1-2ms. El salto de Kafka entre etapas añade menos de 1ms en nuestro despliegue colocado.
Cumplir este presupuesto de forma consistente a 50K eventos/segundo requiere una optimización cuidadosa en cada etapa. Usamos pools de memoria preasignados, serialización zero-copy y escrituras por lotes en ClickHouse. El modelo de puntuación de riesgo se compila a código nativo usando ONNX Runtime, eliminando la sobrecarga del intérprete de Python.
Mark pasó dos semanas perfilando el pipeline antes de encontrar el cuello de botella en nuestra capa de búsqueda distribuida: un único mutex estaba serializando las búsquedas entre todas las goroutines. Tras cambiar a un diseño de bloqueo particionado (sharded), el p99 cayó de 48ms a 9ms. A veces la solución es vergonzosamente simple una vez que la encuentras.