Scoring antifraudă în timp real, la scară
Cum procesează tracio.ai 50K de evenimente/secundă cu un scoring sub 50 ms, folosind stream processing, vectori de semnal precalculați și caching la edge.
Scoring-ul antifraudă la scară necesită o arhitectură fundamental diferită de procesarea în loturi (batch). Când o plată este autorizată sau un cont este creat, ai la dispoziție milisecunde — nu minute — pentru a livra un scor de risc. La tracio.ai procesăm peste 50.000 de evenimente pe secundă, cu o latență mediană de scoring de 22 ms. Acest articol explică arhitectura care face acest lucru posibil.
Pipeline-ul de scoring
Fiecare eveniment care sosește intră într-un pipeline în trei etape: îmbogățirea semnalelor, calculul vectorului și scoring-ul de risc. Îmbogățirea semnalelor atașează la evenimentul brut date de device intelligence — amprenta vizitatorului, rezultatele detecției de boți, IP intelligence și comportamentul istoric. Calculul vectorului transformă aceste semnale îmbogățite într-un vector de trăsături de lungime fixă, optimizat pentru modelul nostru de scoring. Scoring-ul de risc trece vectorul prin modelul nostru antrenat și returnează un scor între 0.0 și 1.0.
Decizia de proiectare esențială este că îmbogățirea și calculul vectorului sunt separate de scoring. Datele de îmbogățire sunt precalculate și puse în cache. Când un vizitator încarcă o pagină, îi calculăm profilul de dispozitiv și îl stocăm în Redis cu un TTL de 60 de minute. Când sosește o cerere de scoring — de regulă declanșată de o plată sau de un login — recuperăm profilul precalculat în loc să-l recalculăm. Astfel latența de scoring scade de la peste 200 ms la sub 30 ms.
Stream processing cu Go
Stratul nostru de ingestie este scris în Go și folosește o arhitectură de tip fan-out. Evenimentele care sosesc ajung prin HTTP POST și sunt plasate imediat pe un canal intern. Un pool de worker goroutines citește din acest canal, efectuează îmbogățirea și scrie evenimentele îmbogățite în ClickHouse pentru analytics și într-o coadă de scoring pentru procesare în timp real. Pool-ul de fan-out se scalează dinamic în funcție de adâncimea cozii.
Am ales Go pentru stratul de ingestie datorită primitivelor sale excelente de concurență și alocării predictibile a memoriei. Fiecare worker goroutine consumă aproximativ 4KB de spațiu de stivă, ceea ce ne permite să rulăm mii de workeri concurenți pe un singur nod. Pauzele sub o milisecundă ale garbage collector-ului sunt esențiale pentru menținerea unei latențe constante la debit ridicat.
Caching la edge și vectori de semnal
Pentru clienții noștri cu cel mai mare volum, implementăm modele de scoring la edge, folosind un cache de vectori de semnal precalculați. Când un dispozitiv este văzut pentru prima dată, îi calculăm vectorul de semnal complet și îl stocăm în cache-ul nostru de edge (implementat pe Cloudflare Workers KV). Cererile de scoring ulterioare pentru același dispozitiv recuperează vectorul din cache și rulează scoring-ul local, la edge, atingând o latență sub 10 ms.
Modelul de scoring de la edge este o versiune distilată a modelului nostru complet — mai mic și mai rapid, dar optimizat pentru aceleași obiective de acuratețe. Reantrenăm modelul de edge săptămânal și livrăm actualizările printr-un rolling deployment, pentru a evita valurile de invalidare a cache-ului. Modelul complet rulează server-side pentru cazurile în care încrederea modelului de edge este sub un prag configurabil.
ClickHouse pentru analytics
Toate evenimentele îmbogățite sunt stocate în ClickHouse, baza noastră de date analitică columnară. Compresia și performanța la interogări ale ClickHouse ne permit să stocăm miliarde de evenimente, susținând în același timp interogări analitice în timp real. Clienții noștri folosesc aceste analytics pentru a înțelege tiparele de fraudă, pentru a ajusta pragurile de scoring și pentru a investiga evenimente individuale.
Folosim materialized views în ClickHouse pentru a menține metrici preagregate: rata de fraudă pe țară, distribuția scoring-ului pe tip de dispozitiv și ratele de fals-pozitiv pe prag. Aceste materialized views se actualizează în timp real, pe măsură ce sosesc evenimentele, oferind metrici gata de afișat în dashboard, fără interogări de agregare costisitoare.
Lecții învățate
Construirea unui sistem de scoring în timp real ne-a învățat câteva lecții. În primul rând, precalcularea este cea mai importantă optimizare — orice muncă pe care o poți face înainte de sosirea cererii de scoring este muncă ce nu se scade din bugetul tău de latență. În al doilea rând, modelul de concurență din Go se potrivește bine procesării de evenimente cu debit ridicat, dar trebuie să fii disciplinat în privința alocării memoriei, pentru a evita presiunea asupra GC. În al treilea rând, implementarea la edge este transformatoare pentru latență, dar necesită o gestionare atentă a modelelor, pentru a evita predicțiile învechite.