בניית צינור אנליטיקת הונאות בזמן אמת
סקירת ארכיטקטורה: קליטת 50K אירועים בשנייה, העשרה באמצעות אותות חכמים, ודירוג סיכון בפחות מ-10ms באמצעות מנוע ה-streaming שלנו.
עיבוד של 50,000 אירועי טביעת אצבע בשנייה, העשרת כל אחד מהם באותות חכמים, והחזרת ציון סיכון בפחות מ-10 מילישניות מחייבים ארכיטקטורת streaming מתוכננת בקפידה. מאמר זה עובר על הצינור שלנו מקליטה ועד החלטה.
שכבת הקליטה
האירועים מגיעים כבקשות HTTPS POST מסוכן ה-JavaScript שלנו הרץ בדפדפני המבקרים. כל אירוע מכיל את מטען האותות המוצפן — בדרך כלל 8-12KB של נתונים דחוסים המכסים 130+ אותות דפדפן. שרתי הקצה שלנו מסיימים את ה-TLS, מאמתים את חתימת הבקשה, ומעבירים את המטען לצינור העיבוד.
אנו משתמשים בפריסה רב-אזורית שבה שרתי הקצה ממוקמים יחד עם צמתי ה-CDN של לקוחותינו. הדבר שומר על זמן הלוך-ושוב ברשת מתחת ל-20ms עבור 95% מהבקשות ברחבי העולם. שרתי הקצה הם שירותי Go חסרי מצב (stateless) הרצים מאחורי מאזן עומסים, ומתרחבים אופקית בהתאם לנפח הבקשות.
חילוץ אותות
שלב העיבוד הראשון מפענח ומנתח את מטען האותות. כל אות מחולץ, מאומת וממופה לטיפוס. גיבובי Canvas מאומתים מול ערכים בלתי אפשריים ידועים (המצביעים על חסימת Canvas או זיוף). פרמטרי WebGL מאומתים באופן צולב לצורך עקביות. תכונות Navigator נבדקות מול צירופים תקפים ידועים.
שלב זה גם מבצע נורמליזציה של האותות. מחרוזות User Agent מנותחות לרכיבים מובנים (דפדפן, גרסה, מערכת הפעלה, מכשיר). ממדי המסך מנורמלים כדי להתחשב בקנה המידה של ה-DPI. היסטי אזור הזמן מאומתים מול נתוני מיקום גאוגרפי של ה-IP.
העשרת Smart Signals
לאחר מכן האותות המחולצים מועשרים בניתוח Smart Signals — שכבת המודיעין שלנו בצד השרת. זה כולל זיהוי גלישה בסתר (השוואת דפוסי אותות מול חתימות ידועות של גלישה פרטית), זיהוי VPN (הצלבת נתוני IP עם אותות אזור זמן ולוקאל), זיהוי שיבוש דפדפן (איתור חוסר עקביות המעיד על זיוף אותות), וזיהוי מכונות וירטואליות (זיהוי פרופילי חומרה המשויכים ל-VMware, VirtualBox ומכונות וירטואליות בענן).
כל אות חכם מחושב באופן עצמאי ומפיק גם תוצאה בוליאנית וגם ציון ביטחון. שלב ההעשרה מוסיף 24 אותות נוספים לכל אירוע, ומספק הערכת איומים מקיפה החורגת מעבר למה שאיסוף בצד הלקוח לבדו יכול להשיג.
מנוע דירוג הסיכון
האירוע המועשר מועבר למנוע דירוג הסיכון שלנו — מודל עץ החלטה מבוסס gradient boosting שאומן על מיליוני אירועים מתויגים. המודל שוקל את כל 130+ האותות הגולמיים, 24 האותות החכמים ומספר תכונות נגזרות: מדדי מהירות (כמה אירועים מהמכשיר הזה ב-5 הדקות, בשעה וב-24 השעות האחרונות), דפוסי התנהגות היסטוריים וציוני מוניטין רשת.
המודל מפיק ציון סיכון בין 0 ל-100, יחד עם הגורמים התורמים המרכזיים. ציון של 85, למשל, עשוי להיות מלווה בגורמים כמו "זוהה VPN", "מצב גלישה בסתר" ו"מהירות גבוהה — 47 אירועים ב-5 דקות". סבירות זו קריטית עבור אנליסטי הונאות שצריכים להבין מדוע אירוע מסוים סומן.
שכבת אחסון ושאילתות
כל האירועים נשמרים ב-ClickHouse — מסד נתונים עמודתי המותאם לשאילתות אנליטיות על מערכי נתונים גדולים. ClickHouse מטפל בנפח הכתיבה שלנו (50K אירועים בשנייה) ללא מאמץ, והאחסון העמודתי שלו מאפשר שאילתות אנליטיות בתת-שנייה על מיליארדי שורות.
אנו משתמשים באסטרטגיית שימור רב-שכבתית. נתונים חמים (7 הימים האחרונים) מאוחסנים על כונני NVMe SSD לתגובת שאילתה מתחת ל-100ms. נתונים פושרים (7-90 ימים) על כונני SSD רגילים. נתונים קרים (90+ ימים) נדחסים ומועברים לאחסון אובייקטים, ניתנים לשאילתה אך בזמן השהיה גבוה יותר.
Kafka כעמוד השדרה
Apache Kafka מקשרת את הצינור יחד. כל שלב קורא וכותב לנושאי (topics) Kafka. שכבת הקליטה כותבת אירועים גולמיים. שלב חילוץ האותות קורא אירועים גולמיים וכותב אירועים מחולצים. שלב העשרת Smart Signals קורא אירועים מחולצים וכותב אירועים מועשרים. מנוע דירוג הסיכון קורא אירועים מועשרים וכותב אירועים מדורגים.
ארכיטקטורה זו מספקת מספר יתרונות: ניתן להרחיב שלבים באופן עצמאי, כשלים בשלב אחד אינם משפיעים על אחרים, ואנו יכולים לשחזר אירועים דרך כל שלב לצורך ניפוי באגים או עיבוד מחדש. קבוצות הצרכנים (consumer groups) של Kafka מאפשרות עיבוד מקבילי בתוך כל שלב, וסמנטיקת ה-exactly-once שלה מבטיחה שאף אירוע אינו מעובד פעמיים או אובד.
תקציב זמן ההשהיה
יעד זמן ההשהיה שלנו מקצה לקצה הוא 10ms מהרגע שבו מטען האותות המועשר מגיע לצינור העיבוד ועד לרגע שבו מוחזר ציון הסיכון. כך מתפרק התקציב: חילוץ האותות אורך 1-2ms, העשרת Smart Signals אורכת 3-4ms, דירוג הסיכון אורך 2-3ms, וסריאליזציה ותגובה אורכות 1-2ms. הקפיצה של Kafka בין השלבים מוסיפה פחות מ-1ms בפריסה הממוקמת-יחד שלנו.
עמידה עקבית בתקציב זה בקצב של 50K אירועים בשנייה מחייבת אופטימיזציה קפדנית בכל שלב. אנו משתמשים במאגרי זיכרון שהוקצו מראש, סריאליזציית zero-copy, וכתיבות ClickHouse מקובצות. מודל דירוג הסיכון מהודר לקוד נייטיב באמצעות ONNX Runtime, מה שמבטל את התקורה של מפרש Python.
מארק בילה שבועיים בפרופיילינג של הצינור לפני שמצא את צוואר הבקבוק בשכבת החיפוש המבוזרת שלנו — mutex יחיד ביצע סריאליזציה של חיפושים על פני כל ה-goroutines. לאחר המעבר לתכנון lock מחולק (sharded), ה-p99 צנח מ-48ms ל-9ms. לפעמים התיקון פשוט עד כדי מבוכה ברגע שמוצאים אותו.