كيف قامت Roblox بتوسيع نطاق منصة Kafka الخاصة بها لتصل إلى أكثر من 18 تريليون رسالة يوميًا
التحسين الشامل لتحقيق كفاءة الأنظمة

خلال العامين الماضيين، قمنا بتوسيع نطاق منصة قائمة انتظار الرسائل الداخلية لدينا بمعدل يزيد عن 2.5 ضعف كل عام لتصل إلى أكثر من 18 تريليون رسالة يوميًا. ونقوم حاليًا بمعالجة أكثر من 300 مليون رسالة في الثانية مع الحفاظ على نسبة توفر تبلغ 99.995%. وقد أصبحت منصة قائمة انتظار الرسائل هذه، المبنية على Apache Kafka، جزءًا أساسيًا من الطريقة التي ننقل بها البيانات عبر الشركة. فهي تدعم أحمال العمل مثل أحداث التحليلات، ومسارات الإشراف، وأنظمة التوفيق بين الأطراف، وغيرها الكثير. هذه الأرقام مثيرة للإعجاب، لكن القصة الأكثر أهمية هي كيف وصلنا إلى هذا المستوى.
تأثير التحسين الشامل من البداية إلى النهاية
هناك فكرة خاطئة شائعة حول الأنظمة واسعة النطاق وهي أن السعة هي في الغالب مشكلة تتعلق بالأجهزة. ومن واقع خبرتنا، فإن التحسينات الأكثر تأثيرًا تتحقق من خلال التعامل مع قابلية التوسع باعتبارها مشكلة هندسية شاملة من البداية إلى النهاية.
قامت الفرق في جميع أنحاء Roblox ببناء منصات متنوعة فوق قائمة انتظار الرسائل، بما في ذلك مسارات تدريب الذكاء الاصطناعي، وتجريدات معالجة التدفق، وأنظمة القياس عن بُعد. تتيح لنا الشراكة مع مالكي هذه المنصات المساعدة في ضمان الالتزام بأفضل الممارسات، مثل تمكين المعالجة المجمعة والضغط. وينتج عن ذلك أنظمة فعالة دون إشراك المستخدمين النهائيين في إعدادات التكوين التفصيلية.

يعد التنسيق مع الفرق التي تستخدم المنصة بشأن أولويات العمل، والقياس، ومعايير النجاح أمرًا بالغ الأهمية، ويساعد على تعزيز التعاون بين الفرق. تختلف المقاييس الرئيسية بين طبقات النظام: فبينما قد نقوم بتحسين خوادم Kafka للتعامل بكفاءة مع أحجام كبيرة من البيانات باستخدام عدد أقل من الأجهزة، قد يرغب المستخدمون النهائيون في تحسين زمن الاستجابة من البداية إلى النهاية حتى مستوى الميلي ثانية، أو تحسين الوقت الإجمالي اللازم لمهمة الدُفعات الخاصة بهم لإكمال كتابة البيانات.
ليست كل حركة المرور متساوية
أحد الدروس الرئيسية التي تعلمناها هو أن المنصات واسعة النطاق تكون أكثر موثوقية عندما لا تعامل كل حركة المرور على قدم المساواة. تتطلب بعض أحمال العمل زمن انتقال منخفضًا جدًّا وحماية قوية أثناء فترات الذروة، مثل أنظمة التوفيق بين الأطراف لدينا، التي تعمل بزمن انتقال من البداية إلى النهاية أقل من 10 مللي ثانية. وهناك أحمال عمل أخرى ذات حجم هائل ولكنها أكثر تسامحًا مع التأخير، مثل خطوط أنابيب استيعاب أحداث التحليلات لدينا، والتي يمكن أن تعمل بسلاسة حتى مع وجود زمن انتقال من طرف إلى طرف يبلغ عدة ثوانٍ. إذا تم التعامل مع كلا النوعين بنفس الطريقة، فإن حركة المرور ذات الحجم الأكبر قد تحجب حركة المرور الأكثر أهمية للأعمال، خاصةً أثناء ذروة الحمل.
لحل هذه المشكلة، نقوم بتجميع حركة المرور وفقًا لمتطلبات حالات الاستخدام لضمان دعم كل حالة بشكل جيد. التوازن بين زمن الوصول من البداية إلى النهاية وسعة النقل في Kafka هو أحد الاعتبارات الأساسية عند إعداد حالات استخدام جديدة. وينطبق هذا على مسار البيانات من المُنتج إلى الخادم إلى المستهلك: فكل واحد منهم له تكوينات يمكن ضبطها لتحسين سعة النقل أو زمن الوصول. يمكن ضبط الإعدادات من جانب العميل لتناسب حالات الاستخدام الفردية، لكن الإعدادات من جانب الخادم أقل مرونة، حيث إنه من غير الممكن الحفاظ على مجموعة مخصصة لكل حالة استخدام منفصلة.
نطبق هذا النهج المتمثل في تحسين كل مجموعة لحالات الاستخدام التي تخدمها عبر المكدس وصولاً إلى طبقة الأجهزة.
لا تزال الأجهزة ذات أهمية حاسمة
بدأنا بتشغيل Kafka على أجهزة مزودة بأقراص صلبة (HDD) بتكوين RAID10. مع نمو حجم حركة المرور، أصبحت سعة عمليات الإدخال/الإخراج (I/O) للأقراص في أجهزتنا هي العنق الزجاجي الرئيسي الذي يحد من معدل نقل البيانات لـ Kafka لكل خادم. لمعالجة ذلك، قمنا بتحسينين. قمنا بتحويل الوسطاء (brokers) لاستخدام محركات الأقراص الصلبة (SSD) قدر الإمكان، مما أدى إلى تحويل العنق الزجاجي من سعة عمليات الإدخال/الإخراج للأقراص إلى معدل نقل البيانات عبر الشبكة أو مساحة القرص (نظرًا لأن محركات الأقراص الصلبة التي حصلنا عليها كانت ذات مساحة تخزين أقل). أدى ذلك إلى زيادة إنتاجية إدخال/إخراج الأقراص بمقدار 10 أضعاف. كما بدأنا في تحويل محركات الأقراص الصلبة المتبقية لدينا من RAID10 إلى RAID0. وقد أدى ذلك إلى مضاعفة سعة إدخال/إخراج الأقراص تقريبًا، حيث إن كل عملية كتابة باستخدام RAID0 لا تتطلب سوى كتابة على قرص واحد بدلاً من اثنين.
لكن المقابل هو أنه نظرًا لأن كل نسخة متماثلة للرسالة تُكتب على قرص واحد لكل وسيط بدلاً من اثنين، فإن الانتقال من RAID10 إلى RAID0 قد ينطوي على مخاطر تتعلق بالموثوقية. وللحفاظ على الموثوقية، عملنا على حالات الاستخدام المهمة لزيادة عمليات التأكيد (acks) ونسخ البيانات المتماثل، بما في ذلك النسخ المتماثل إلى مناطق متعددة.
تطلب الاستفادة الكاملة من قدرات التخزين والإنتاجية لكل جهاز بذل جهد إضافي. قمنا بتحسين تخصيصات الذاكرة وإعدادات إدارة ذاكرة التخزين المؤقت للصفحات بحيث يتمكن Kafka من تخزين الرسائل مؤقتًا وتقديم عمليات القراءة أو البيانات الحديثة من الذاكرة، مع اللجوء إلى القرص واستهلاك عمليات الإدخال/الإخراج في الثانية (IOPS) القيمة فقط عند الضرورة، مثل عند قراءة البيانات التاريخية.
كما قمنا بإجراء اختبارات قياس الأداء لفهم حدود الأجهزة وتحديد الحدود التي يتعين علينا وضعها على مستوى البرمجيات. في الممارسة العملية، يعني هذا ضبط حدود القراءة والكتابة لوسطاء Kafka، والتي تختلف بناءً على الأجهزة التي تعمل عليها المجموعات. يمكن لأجهزتنا المزودة بمحركات أقراص SSD التعامل مع إنتاجية أعلى لكل وسيط، في حين أن أجهزتنا المزودة بمحركات أقراص HDD أكثر ملاءمة لحالات الاستخدام التي تتطلب الاحتفاظ بالبيانات التاريخية على المدى الطويل.
البناء من أجل الموثوقية
تعد منصة قوائم الانتظار مكونًا أساسيًّا في البنية التحتية لـ Roblox، ويُعد الحفاظ على الموثوقية أمرًا بالغ الأهمية. وقد كان الاختبار قبل الإطلاق، بالإضافة إلى الاختبار المستمر لسيناريوهات الأعطال (التي تُسمى أحيانًا «تمارين يوم المباراة») عاملاً أساسيًّا في التحقق من أن بنيتنا التحتية قادرة على الصمود أمام أنماط الأعطال مثل تعطل مضيف واحد، أو تعطل وحدة الحامل، أو مشكلات الشبكة، والعديد من الحالات الأخرى. وقد مكنت منصة الاختبار الداخلية للفوضى التابعة لفريق الموثوقية لدينا من تبسيط عملية محاكاة سيناريوهات الأعطال المختلفة. تساعد هذه الاختبارات في تحديد تحسينات النظام أو حالات التراجع، وبناء التميز التشغيلي من خلال التحقق بانتظام من صحة التنبيهات وضمان إلمام المشغلين بالخطوات اللازمة للتعامل مع المشكلات المختلفة — حتى النادرة منها.
كما قمنا بتصميم وتنفيذ عمليات التحويل التلقائي (failover) التي يمكنها استعادة وظائف قائمة الانتظار بسرعة لحالات الاستخدام المعتمدة عليها. حتى في حالة الفشل التام لمجموعة (cluster) فردية، فإننا قادرون على تحويل العملاء إلى مجموعة سليمة ذات سعة كافية. ولضمان توفر سعة غير مستخدمة كافية، نحتفظ بمجموعة Kafka احتياطية. وهذا يساعد في القضاء على أي مخاطر تتعلق بمشاكل «الجيران المزعجين» (noisy neighbor) عند تحويل حركة المرور بين المجموعات النشطة.
يوضح الرسم التوضيحي أدناه الخطوات العامة لتنفيذ عملية التحويل التلقائي. أولاً، يحدد المشغل نطاق عملية التحويل التلقائي. بعد ذلك، يتم إنشاء الموضوعات وقوائم التحكم في الوصول (ACLs) على المجموعة الاحتياطية من خلال عملية جماعية آلية. وأخيرًا، يقوم المشغل بتحديث تكوينات خدمة مستوى التحكم لدينا، والتي يستطلعها العملاء لتحديد ما إذا كانت هناك حاجة إلى إعادة الاتصال. الرسم التوضيحي أدناه مخصص لحالات الاستخدام العامة في الوقت الفعلي. لدينا استراتيجيات وأدوات إضافية لحالات الاستخدام والسيناريوهات الأخرى، بما في ذلك النسخ المتطابق للمواضيع باستخدام Mirror Maker 2، وأدوات ملء الفجوات في البيانات، والمزيد.

تفرض Roblox متطلبات صارمة في مجال الأمان، والذي يُعد أيضًا جزءًا أساسيًا من الموثوقية. وقد قمنا بتنفيذ ميزات أمان قياسية مثل التشفير أثناء النقل (باستخدام mTLS)، والتشفير أثناء التخزين (باستخدام القرص المشفر)، ومتطلبات مدة الاحتفاظ بالبيانات، والمصادقة/التفويض باستخدام كيانات Kafka وقوائم التحكم في الوصول (ACLs). كما نقوم بتدوير بيانات اعتماد مستخدمينا تلقائيًا لزيادة تحسين الأمان.
بالإضافة إلى ذلك، قمنا بتطوير معالجة مخصصة في مستوى التحكم لدينا لتسهيل إجراء تصحيحات نظام التشغيل وتفريغ الرفوف بسرعة. أثناء إجراء تصحيحات نظام التشغيل، نحتفظ بالبيانات على القرص حتى تتمكن الأجهزة التي تم تصحيحها من استعادة حالتها السليمة بسرعة بعد إعادة انضمامها إلى مجموعة Kafka. وبهذه الطريقة، يمكننا إجراء تصحيحات على أسطولنا بالكامل في غضون 30 يومًا، حتى مع استمرار نموه. باستخدام أدوات مثل Cruise Control، نقوم بنسخ بياناتنا بطريقة تراعي الحوامل، بحيث يمكن فصل الحوامل بالكامل عن الشبكة لأغراض الصيانة وتطبيق تصحيحات الشبكة دون التأثير على توفر البيانات.
الطريق إلى الأمام
يتمحور الفصل التالي لمنصة قوائم الانتظار لدينا حول جعل المنصة أكثر بساطة للمطورين مع الاستمرار في تحسين المرونة والعزل. نحن نستثمر في تجريدات جديدة، بما في ذلك وكلاء المنتجين والمستهلكين بالإضافة إلى الموصلات المدارة بالكامل. ستعمل هذه الأنظمة على فصل فرق التطبيقات بشكل أكبر عن تعقيدات البنية التحتية وستجعل منصاتنا أسهل في التبني والإدارة على نطاق واسع. على سبيل المثال، سيمكّن وكيل المستهلك من تطبيق نمط المستهلكين المتنافسين، مما يسمح للمنصة بدعم نطاق أوسع من حالات الاستخدام وفصل توسيع نطاق المعالجات عن توسيع نطاق أقسام كافكا. وهذا أمر مهم لحالات الاستخدام مثل معالجة موجات ضخمة من الإشعارات، التي لا تتطلب ترتيبًا ويمكن أن تستفيد من زيادة عدد المعالجات مؤقتًا دون الالتزام بأهداف تسليم من البداية إلى النهاية.
لا يقتصر توسيع نطاق كافكا على توسيع عدد المجموعات وحجمها فحسب. بل يتعلق الأمر ببناء الانضباط الهندسي والتجريدات والنموذج التشغيلي الذي يسمح لـ Roblox بمواصلة رحلتنا لربط مليار شخص كل يوم بالتفاؤل والكياسة.
شكر وتقدير: شكرًا لـ داني يوان وجورج لي على مساهماتهما الهامة في منصة قائمة الانتظار في Roblox.


