كيف استخدمت Roblox Theta Sketches لتوسيع نطاق تحليلات المبدعين

تعد التحليلات أمرًا ضروريًا لألعاب اليوم متعددة اللاعبين في الوقت الفعلي. في Roblox، نركز على تطوير أدوات قياس لمساعدة المبدعين لدينا على الازدهار. تمنح تحليلاتنا المجانية والجاهزة للاستخدام المبدعين رؤية فورية لنمو تجاربهم واكتساب المستخدمين والاحتفاظ بهم، مما يساعدهم على تحقيق أقصى قدر من النجاح.
يعد بناء أنظمة التحليلات الحديثة التي يعتمد عليها ملايين المبدعين في Roblox تحديًا مهمًا. لمواجهة هذا التحدي، قمنا بتحسين محرك استعلامات التحليلات لدينا بحيث يمكن لمجموعة معالجة مكونة من 120 نواة أن تخدم أكثر من 6 ملايين استعلام يوميًا من حوالي 300,000 زائر يومي يصلون إلى 86 تيرابايت من البيانات. في قلب حلنا توجد قاعدة بيانات للمعالجة التحليلية عبر الإنترنت (OLAP) اخترناها لقابليتها للتوسع وتكاملها مع خوارزميات التقريب. باستخدام مزيج من تقنيات تجميع البيانات بالإضافة إلى خوارزميات HyperLogLog و Theta Sketch، نقدم تحليلات لملايين تجارب Roblox1.
دليل تمهيدي حول تحليلات OLAP
كلما زادت كمية البيانات التي يتم الاستعلام عنها، زاد الوقت المستغرق لإنتاج النتائج. عندما نتمكن من تقليل البيانات المطلوبة وتسريع عملية التحليل، يمكن للمبدعين الحصول على رؤى شبه فورية من إجراءاتهم. تتضمن بعض التقنيات التي نستخدمها ما يلي:
- التخزين العمودي: يقرأ OLAP، Druid، الأعمدة الضرورية فقط.
- مرشحات التقسيم والفرز: يقرأ OLAP فقط الملفات ذات الصلة التي تفهرس مباشرة إلى كتل البيانات المطلوبة.
- التجميع: يقوم OLAP بتجميع الأحداث جزئيًا باستخدام التجميعات الشائعة.
تتيح عمليات التجميع، على وجه الخصوص، لـ OLAPs العمل بين أكبر محركات استعلامات SQL، مثل Spark أو Presto (مع زمن انتقال يصل إلى عشرات الثواني)، والاستعلامات المحددة أو SQL المحدود، والتي عادةً ما تقدم بيانات مجمعة بالكامل. مع عمليات التجميع، يتم ترتيب الاستعلامات حسب تجمعات الأبعاد، مما يؤدي إلى انخفاضات كبيرة في إجمالي عدد الصفوف. عند النظر إلى مليارات أو حتى تريليونات من الأحداث الأولية، قد يكون من الأكثر كفاءة تجميعها في ملايين المجموعات التي يمكن تجميعها بزمن انتقال أقل من ثانية. على سبيل المثال:

في حين أن عمليات التجميع توفر مزايا التخفيض المذكورة أعلاه، إلا أن بعض المقاييس لا تستجيب لها، بما في ذلك الاستعلامات التي تتطلب فرزًا كاملاً للجدول من البيانات الأولية، مثل عمليات العد المتميزة، والنسب المئوية، واستعلامات التكرار.
لحسن الحظ، يمكننا التغلب على هذه القيود باستخدام تقنيات تعطي نتيجة تقريبية محدودة إحصائيًا استنادًا إلى هياكل بيانات معقدة تحتوي على عينة من مجموعة البيانات الكاملة. تم تصميم هياكل البيانات هذه للاستخدام في تقنيات التجميع وتجمع بين عددين متميزين عبر عملية اتحاد، على غرار جمع رقمين معًا.
تحليل أحمال عمل تحليلات Roblox
في Roblox، نوفر للمبدعين لوحة تحكم مركزية حيث يمكنهم العثور على أهم الإحصاءات الخاصة بهم. وتشمل هذه:
- التفاعل: المستخدمون النشطون يوميًا (DAU)، والمستخدمون النشطون شهريًا (MAU)، ومعدل الاحتفاظ، ومسارات التحويل
- تحقيق الدخل: الإيرادات، ومتوسط الإيرادات لكل مستخدم، والمبيعات، والاقتصاد
- بيانات الاكتساب
- تخصيص الصور المصغرة ونتائج التجارب
- تحليلات توصيات الصفحة الرئيسية
- والمزيد قادم.

اختيار محرك الاستعلام وتحسينه
التغلب على تحديات الأداء
في الجولة الأخيرة من اختبار الظل للإنتاج، اكتشفنا تحديًا مهمًا: كان من الضروري تعزيز أداء استعلامات MAU بعد التحول من الاستعلامات الكبيرة الفردية إلى أنماط التجميع اليومية. هذه الأمور حاسمة بالنسبة لتصورات تحليلات المبدعين لدينا.
وجدنا أن بنية الاستعلام أثرت بشكل كبير على الأداء الأساسي لحل OLAP الخاص بنا. غالبًا ما تدفع الاستعلامات القياسية ذات مراحل التنفيذ المتعددة (مثل عبارات "GROUP BY" المتداخلة2) أجزاء كبيرة من العمل إلى العقد الوسيطة خفيفة الوزن.
هذه مشكلة كلاسيكية في البيانات الضخمة حيث ينتهي الأمر بتنفيذ جزء من الاستعلام على عقد خدمة صغيرة مهمة. كنا نتوقع أن تعمل هياكل البيانات التقريبية لدينا مثل عمليات العد أو الجمع البسيطة، لكننا اكتشفنا أنها كانت تتصرف في الواقع بشكل مختلف تمامًا.
يوضح الشكل أدناه هذه المشكلة. فهو يوضح كيف تقوم العقد التاريخية لدينا بالتجميع الجزئي، حيث تقوم بتجميع Theta Sketch لكل يوم ثم إعادة توجيه بياناتها إلى الوسيط. ثم يحاول الوسيط دمج كل رسم يومي كبير في قيمة شهرية واحدة لكل يوم. بالنسبة لـ 30 يومًا من MAU، كان هذا يعني دمج 1800 Theta Sketches ذات الحجم الأقصى على وسيط، مما أدى إلى استعلام أبطأ وعرضة للفشل واستحوذ على وحدة المعالجة المركزية للوسيط.

كان حلنا هو تشغيل OLAP باستخدام عدد أقل من العمال التاريخيين الكبار لتعظيم محلية البيانات لمصادر البيانات التي تعتمد على استعلامات التقريب. في الممارسة العملية، أدى ذلك إلى إعادة عملية دمج كان من الممكن أن تتطلب أكثر من 100 ميغابايت من معالجة البيانات إلى العقد التاريخية لدينا.
لتحقيق ذلك في SQL، استخدمنا ربطًا مضمنًا لجعل الاستعلامات تنشر المعلومات الضرورية إلى العقد التاريخية وأعددنا استعلامًا مع قائمة بتواريخ النتائج المضمنة. يمكن بعد ذلك لكل تاريخ نتيجة جمع البيانات ذات الصلة من شرائح العقد التاريخية. ثم يتم تمرير البيانات مرة أخرى إلى الوسيط، حيث يتم دمج النتائج بسرعة في خريطة واحدة لتاريخ النتيجة إلى بيانات المقاييس، كما هو موضح أدناه.

كان لهذا التحسين تأثير كبير على أداء الاستعلامات واسعة النطاق. بالنسبة لتفاصيل عدد المستخدمين الشهريين النشطين (MAU) لتجربة رئيسية حسب البلد، تحسن متوسط أداء الاستعلام بمقدار 5 أضعاف (من 17.53 ثانية إلى 3.23 ثانية)، كما هو موضح في الرسم البياني أدناه. كما لاحظنا انخفاضًا بمقدار 50 ضعفًا في وقت وحدة المعالجة المركزية (CPU) على الوسيط (من 16.83 ثانية إلى 0.34 ثانية).
على الرغم من تباين النتائج، فإن هذا يسلط الضوء على أهمية التعامل مع العمليات المعقدة (مثل دمج ملايين المخططات) بحذر. قد يؤدي افتراض أن هذه العمليات تعادل عمليات التجميع البسيطة إلى مشكلات كبيرة في الأداء، خاصةً في الأنظمة التي تشيع فيها عمليات تجميع العملاء في المرحلة الأخيرة.
الملخصات ومكعب ثيتا النظري

كما استكشفنا مكعب ثيتا، أو نهجًا عامًا لسد الفجوة بين جداول التجميع الأساسية والجداول الأولية بالكامل عبر تقاطعات المجموعات التقريبية. يعالج هذا النهج قيدًا أساسيًا: تفقد جداول التجميع ميزتها عندما تحتاج الاستعلامات إلى لمس العديد من طبقات الأبعاد عالية الكاردينالية. وذلك لأن كل بُعد يتسبب في توسيع نطاق كاردينالية التجميع إلى ∏dim (حاصل ضرب الأبعاد).
لقد صممنا نظامًا يقوم بالتجميع حسب مجموعات الأبعاد المشتركة مع حد أقصى للعددية، مما يسمح باستعلامات أداء التجميع على أي شيء في المجموعة. ثم، عند البحث عن مجموعات من الأبعاد عبر المجموعات، نحاول إجراء ربط تقريبي عبر المجموعات ونعرض نتائج المقاييس مع تقديرات الأخطاء. يتم توجيه الاستعلام الذي يحتوي على تقدير خطأ مرتفع إلى جدول خام، حيث تسمح المرشحات العديدة بإجراء تحسينات دفع كبيرة.


نظرًا لأننا نستطيع حساب معدل الخطأ هذا بسرعة، فإنه يُعد أيضًا مؤشرًا قويًا على أن قراءة الجدول الخام ستكون على الأرجح فعالة. في الحالات التي تكون فيها البيانات المتداخلة صغيرة نسبيًا مقارنة بالاتحاد (مثل المتحدثين باللغة اليابانية في ألمانيا)، سيتم تصفية عدد كبير من صفوف الجدول الخام. ويؤدي ذلك إلى تحسينات دفع لأسفل فعالة. إن النظام الذي يستخدم مجموعات الأبعاد، وعمليات الربط التقريبية، وقراءة الجداول الأولية القائمة على الأخطاء، سيعمل بالفعل على تعظيم أداء التجميع في الاستعلامات التي تتناسب مع التقريب.
بالنسبة إلى Roblox، سيكون هذا الحل أكثر قابلية للتطبيق في المستوى التالي من التوسع لدينا — ربما لتحليل المسار الديناميكي أو الأحداث المخصصة — في حين أن نسخة التجميع البسيطة الحالية لدينا تلبي احتياجات اليوم.
بناء منصة للخدمة الذاتية
بعد تحسين الوسيط الخاص بنا، اتجهنا نحو بناء أدوات لإدخال واستعلام مجموعات البيانات المضافة إلى حل OLAP الخاص بنا. قمنا ببناء مكتبة مفتوحة المصدر لـ Spark و Trino UDAF لوظائف datasketch الخاصة بنا، مما سمح لـ Spark باستخدام نفس تنسيق datasketch الثنائي مثل OLAP6 الخاص بنا. أدى ذلك إلى إبقاء معظم أعباء الحوسبة لدينا في Spark وساعد في توحيد التقريب عبر Roblox، مما قد يقلل من تكاليف الحوسبة بنسبة تصل إلى 80٪ لبعض مجموعات البيانات.
لقد قمنا بتبسيط عملية الإدخال باستخدام امتداد داخلي لجدول مهامنا الدفعية وحددنا واجهة برمجة تطبيقات (API) على غرار إطار البيانات (dataframe) توجه المطورين لاتخاذ قرارات بشأن المقاييس والأبعاد النهائية، مما يقلل من تأثير الاستعلامات المفتوحة. كما قمنا بإتاحة بعض نماذج سير العمل كمصدر مفتوح لتوضيح كيفية تحميل هذه البيانات والاستعلام عنها في OLAP الخاص بنا.
توفر مجموعات بيانات التحليلات المُحسّنة لدينا الآن رؤى عميقة لمبدعينا. أدت تحسيناتنا إلى تحسين الأداء المتوسط بمقدار 4 أضعاف والأداء في أسوأ الحالات بمقدار 50 ضعفًا. تتيح منصة الخدمة الذاتية لفريق تحليلات المبدعين لدينا الاستمرار في تكرار مجموعات البيانات الجديدة للمطورين. نحن متحمسون لرؤية المطورين من جميع الأحجام يستخدمون هذه الأدوات لإنشاء تجارب مذهلة على Roblox.
1 محسوبة على أساس آخر 60 يومًا من العوالم الفريدة التي تم الوصول إليها بأي شكل
2 مثل استعلام
MAU البسيط هذا 3 النتائج من 21 إلى 28 مارس 2025
4 تم تنفيذها على النحو التالي: SELECT c.experience_id, c.country, p.platform, THETA_INTERSECT(c.user_theta, p.user_theta) from (select experience_id, country, user_theta from theta_cube where agg_level = country) c union (select experience_id, platform, user_theta from theta_cube where agg_level = platform) p
5 https://datasketches.apache.org/docs/Theta/ThetaSketchSetOpsAccuracy.html
6 من خلال دالة druid sql COMPLEX_DECODE_BASE64('HLLSketch', sketch_col_name ).


