Aufbau einer Echtzeit-Betrugsanalyse-Pipeline
Architektur-Rundgang: 50.000 Ereignisse/Sekunde aufnehmen, mit Smart Signals anreichern und Risiko in unter 10ms mit unserer Streaming-Engine bewerten.
50.000 Fingerprint-Ereignisse pro Sekunde zu verarbeiten, jedes mit Smart Signals anzureichern und einen Risikowert in unter 10 Millisekunden zurückzugeben, erfordert eine sorgfältig entworfene Streaming-Architektur. Dieser Artikel führt durch unsere Pipeline von der Aufnahme bis zur Entscheidung.
Aufnahmeschicht
Ereignisse treffen als HTTPS-POST-Anfragen von unserem JavaScript-Agenten ein, der in den Browsern der Besucher läuft. Jedes Ereignis enthält die verschlüsselte Signal-Nutzlast — typischerweise 8-12KB komprimierte Daten, die 130+ Browser-Signale abdecken. Unsere Edge-Server terminieren TLS, validieren die Anfragesignatur und leiten die Nutzlast an die Verarbeitungs-Pipeline weiter.
Wir setzen ein Multi-Region-Deployment ein, bei dem Edge-Server bei den CDN-Knoten unserer Kunden kolokalisiert sind. Das hält den Netzwerk-Round-Trip weltweit für 95% der Anfragen unter 20ms. Die Edge-Server sind zustandslose Go-Dienste, die hinter einem Load Balancer laufen und horizontal nach Anfragevolumen skalieren.
Signalextraktion
Die erste Verarbeitungsstufe entschlüsselt und parst die Signal-Nutzlast. Jedes Signal wird extrahiert, validiert und typisiert. Canvas-Hashes werden gegen bekannte unmögliche Werte geprüft (die auf Canvas-Blockierung oder -Spoofing hinweisen). WebGL-Parameter werden auf Konsistenz kreuzvalidiert. Navigator-Eigenschaften werden gegen bekannte gültige Kombinationen geprüft.
Diese Stufe führt außerdem eine Signalnormalisierung durch. User-Agent-Strings werden in strukturierte Komponenten zerlegt (Browser, Version, OS, Gerät). Bildschirmabmessungen werden normalisiert, um die DPI-Skalierung zu berücksichtigen. Zeitzonenverschiebungen werden gegen die IP-Geolokalisierungsdaten validiert.
Smart-Signals-Anreicherung
Die extrahierten Signale werden anschließend mit der Smart-Signals-Analyse angereichert — unserer serverseitigen Intelligenzschicht. Dazu gehören Inkognito-Erkennung (Vergleich von Signalmustern mit bekannten Signaturen des privaten Surfens), VPN-Erkennung (Abgleich der IP-Daten mit Zeitzonen- und Locale-Signalen), Browser-Manipulationserkennung (Identifikation von Inkonsistenzen, die auf Signal-Spoofing hinweisen) und Erkennung virtueller Maschinen (Erkennung von Hardware-Profilen, die mit VMware, VirtualBox und Cloud-VMs verbunden sind).
Jedes Smart Signal wird unabhängig berechnet und erzeugt sowohl ein boolesches Ergebnis als auch einen Konfidenzwert. Die Anreicherungsstufe fügt jedem Ereignis 24 zusätzliche Signale hinzu und liefert so eine umfassende Bedrohungsbewertung, die über das hinausgeht, was clientseitige Erfassung allein erreichen kann.
Risiko-Scoring-Engine
Das angereicherte Ereignis wird an unsere Risiko-Scoring-Engine übergeben — ein Modell aus gradientenverstärkten Entscheidungsbäumen, trainiert auf Millionen gelabelter Ereignisse. Das Modell berücksichtigt alle 130+ Rohsignale, 24 Smart Signals und mehrere abgeleitete Merkmale: Geschwindigkeitsmetriken (wie viele Ereignisse von diesem Gerät in den letzten 5 Minuten, 1 Stunde und 24 Stunden), historische Verhaltensmuster und Netzwerk-Reputationswerte.
Das Modell gibt einen Risikowert zwischen 0 und 100 aus, zusammen mit den wichtigsten Einflussfaktoren. Ein Wert von 85 könnte zum Beispiel von Faktoren wie „VPN erkannt“, „Inkognito-Modus“ und „hohe Geschwindigkeit — 47 Ereignisse in 5 Minuten“ begleitet sein. Diese Erklärbarkeit ist entscheidend für Betrugsanalysten, die verstehen müssen, warum ein bestimmtes Ereignis markiert wurde.
Speicher- und Abfrageschicht
Alle Ereignisse werden in ClickHouse persistiert — einer spaltenorientierten Datenbank, optimiert für analytische Abfragen über große Datensätze. ClickHouse bewältigt unser Schreibvolumen (50K Ereignisse/Sekunde) mühelos, und seine spaltenorientierte Speicherung ermöglicht analytische Abfragen im Sub-Sekunden-Bereich über Milliarden von Zeilen.
Wir nutzen eine mehrstufige Aufbewahrungsstrategie. Heiße Daten (letzte 7 Tage) liegen auf NVMe-SSDs für Abfrageantworten unter 100ms. Warme Daten (7-90 Tage) liegen auf Standard-SSDs. Kalte Daten (90+ Tage) werden komprimiert und in Objektspeicher verschoben, abfragbar, aber mit höherer Latenz.
Kafka als Rückgrat
Apache Kafka verbindet die Pipeline. Jede Stufe liest von und schreibt in Kafka-Topics. Die Aufnahmeschicht schreibt Roh-Ereignisse. Die Signalextraktionsstufe liest Roh-Ereignisse und schreibt extrahierte Ereignisse. Die Smart-Signals-Anreicherungsstufe liest extrahierte Ereignisse und schreibt angereicherte Ereignisse. Die Risiko-Scoring-Engine liest angereicherte Ereignisse und schreibt bewertete Ereignisse.
Diese Architektur bietet mehrere Vorteile: Stufen können unabhängig skaliert werden, Ausfälle in einer Stufe beeinträchtigen andere nicht, und wir können Ereignisse zum Debuggen oder zur erneuten Verarbeitung durch jede Stufe wieder abspielen. Kafkas Consumer-Gruppen ermöglichen parallele Verarbeitung innerhalb jeder Stufe, und seine Exactly-once-Semantik stellt sicher, dass kein Ereignis zweimal verarbeitet oder verloren wird.
Latenzbudget
Unser Ende-zu-Ende-Latenzziel liegt bei 10ms — vom Moment, in dem die angereicherte Signal-Nutzlast an der Verarbeitungs-Pipeline eintrifft, bis zum Moment, in dem der Risikowert zurückgegeben wird. So gliedert sich das Budget auf: Signalextraktion braucht 1-2ms, Smart-Signals-Anreicherung braucht 3-4ms, Risiko-Scoring braucht 2-3ms, und Serialisierung und Antwort brauchen 1-2ms. Der Kafka-Sprung zwischen den Stufen fügt in unserem kolokalisierten Deployment weniger als 1ms hinzu.
Dieses Budget bei 50K Ereignissen/Sekunde konsistent einzuhalten, erfordert sorgfältige Optimierung auf jeder Stufe. Wir verwenden vorab zugewiesene Speicherpools, Zero-Copy-Serialisierung und gebündelte ClickHouse-Schreibvorgänge. Das Risiko-Scoring-Modell wird mit ONNX Runtime zu nativem Code kompiliert, was den Overhead des Python-Interpreters eliminiert.
Mark verbrachte zwei Wochen mit dem Profiling der Pipeline, bevor er den Engpass in unserer verteilten Lookup-Schicht fand — ein einzelner Mutex serialisierte Lookups über alle Goroutines hinweg. Nach dem Umstieg auf ein sharded Lock-Design fiel p99 von 48ms auf 9ms. Manchmal ist die Lösung peinlich einfach, sobald man sie gefunden hat.