تسجيل الاحتيال في الزمن الحقيقي على نطاق واسع
كيف تعالج tracio.ai 50 ألف حدث/ثانية مع تسجيل دون 50 مللي ثانية باستخدام معالجة التدفّق ومتّجهات الإشارة المحسوبة مسبقاً والتخزين المؤقت عند الحافة.
يتطلّب تسجيل الاحتيال على نطاق واسع بنية مختلفة جذرياً عن المعالجة الدفعية. فعند تفويض عملية دفع أو إنشاء حساب، لديك مللي ثوانٍ — لا دقائق — لتقديم درجة مخاطرة. في tracio.ai، نعالج أكثر من 50٬000 حدث في الثانية بزمن تسجيل وسيط قدره 22 مللي ثانية. تشرح هذه المقالة البنية التي تجعل ذلك ممكناً.
خط أنابيب التسجيل
يدخل كل حدث وارد خطّ أنابيب من ثلاث مراحل: إثراء الإشارة، وحساب المتّجه، وتسجيل المخاطرة. يُرفق إثراء الإشارة بيانات ذكاء الأجهزة — بصمة الزائر، ونتائج كشف الروبوتات، وذكاء عناوين IP، والسلوك التاريخي — بالحدث الخام. ويحوّل حساب المتّجه هذه الإشارات المُثراة إلى متّجه سمات ثابت الطول محسَّن لنموذج التسجيل لدينا. ويمرّر تسجيل المخاطرة المتّجه عبر نموذجنا المُدرَّب ويعيد درجة بين 0.0 و1.0.
القرار التصميمي الأساسي هو فصل الإثراء وحساب المتّجه عن التسجيل. تُحسَب بيانات الإثراء مسبقاً وتُخزَّن مؤقتاً. عندما يحمّل زائرٌ صفحةً، نحسب ملفّه التعريفي للجهاز ونخزّنه في Redis بمدة صلاحية 60 دقيقة. وعندما يصل طلب تسجيل — يُطلَق عادةً بعملية دفع أو تسجيل دخول — نسترجع الملفّ المحسوب مسبقاً بدلاً من إعادة حسابه. يقلّص هذا زمن التسجيل من أكثر من 200 مللي ثانية إلى أقل من 30 مللي ثانية.
معالجة التدفّق باستخدام Go
طبقة الإدخال لدينا مكتوبة بلغة Go وتستخدم بنية توزيع (fan-out). تصل الأحداث الواردة عبر HTTP POST وتُوضَع فوراً في قناة داخلية. يقرأ مجمّع من عمّال goroutines من هذه القناة، وينفّذ الإثراء، ويكتب الأحداث المُثراة إلى ClickHouse للتحليلات وإلى طابور تسجيل للمعالجة في الزمن الحقيقي. يتوسّع مجمّع التوزيع ديناميكياً بناءً على عمق الطابور.
اخترنا Go لطبقة الإدخال بسبب بدائيّاتها الممتازة للتزامن وتخصيصها المتوقَّع للذاكرة. يستهلك كل عامل goroutine نحو 4 كيلوبايت من مساحة المكدّس، ما يتيح لنا تشغيل آلاف العمّال المتزامنين على عقدة واحدة. وتوقّفات كانس المهملات دون المللي ثانية حاسمة للحفاظ على زمن استجابة متّسق عند إنتاجية عالية.
التخزين المؤقت عند الحافة ومتّجهات الإشارة
بالنسبة لعملائنا الأعلى حجماً، ننشر نماذج التسجيل عند الحافة باستخدام ذاكرة مؤقتة لمتّجه إشارة محسوب مسبقاً. عندما يُشاهَد جهازٌ لأول مرة، نحسب متّجه إشارته الكامل ونخزّنه في ذاكرتنا المؤقتة عند الحافة (المنشورة على Cloudflare Workers KV). وتسترجع طلبات التسجيل اللاحقة للجهاز نفسه المتّجه المخزَّن وتنفّذ التسجيل محلياً عند الحافة، محقّقةً زمناً دون 10 مللي ثانية.
نموذج التسجيل عند الحافة هو نسخة مُقطَّرة من نموذجنا الكامل — أصغر وأسرع، لكنه محسَّن لأهداف الدقة نفسها. نعيد تدريب نموذج الحافة أسبوعياً وننشر التحديثات عبر نشر متدرّج لتفادي عواصف إبطال الذاكرة المؤقتة. ويعمل النموذج الكامل على الخادم في الحالات التي تكون فيها ثقة نموذج الحافة دون عتبة قابلة للضبط.
ClickHouse للتحليلات
تُخزَّن جميع الأحداث المُثراة في ClickHouse، قاعدة بيانات التحليلات العمودية لدينا. يتيح لنا ضغط ClickHouse وأداء استعلاماتها تخزين مليارات الأحداث مع دعم الاستعلامات التحليلية في الزمن الحقيقي. يستخدم عملاؤنا هذه التحليلات لفهم أنماط الاحتيال، وضبط عتبات التسجيل، والتحقيق في الأحداث الفردية.
نستخدم العروض المُجسَّدة في ClickHouse للحفاظ على مقاييس مُجمَّعة مسبقاً: معدّل الاحتيال حسب الدولة، وتوزيع التسجيل حسب نوع الجهاز، ومعدّلات الإيجابيات الكاذبة حسب العتبة. تتحدّث هذه العروض المُجسَّدة في الزمن الحقيقي مع وصول الأحداث، ما يوفّر مقاييس جاهزة للوحات المعلومات دون استعلامات تجميع باهظة.
دروس مستفادة
علّمنا بناء نظام تسجيل في الزمن الحقيقي عدة دروس. أولاً، الحساب المسبق هو أهمّ تحسين — فأي عمل يمكنك إنجازه قبل وصول طلب التسجيل هو عمل لا يُحتسَب على ميزانية زمن الاستجابة لديك. ثانياً، نموذج التزامن في Go مناسب تماماً لمعالجة الأحداث عالية الإنتاجية، لكن يجب أن تكون منضبطاً في تخصيص الذاكرة لتفادي ضغط كانس المهملات. ثالثاً، النشر عند الحافة تحويلي لزمن الاستجابة لكنه يتطلّب إدارة دقيقة للنماذج لتفادي التنبّؤات القديمة.