تمت ترجمة المحتوى الموجود على هذا الموقع باستخدام الذكاء الاصطناعي (AI) أو تقنية الترجمة الآلية، وقد تحتوي على أخطاء.

Skip to content

كيف حافظت ذاكرة التخزين المؤقتة لـ Roblox على 1.38 مليار عملية في الثانية (QPS) متجاوزة حدود Redis

التعامل مع زيادة في عدد الزيارات بمقدار 10 أضعاف مع مراعاة الموثوقية والكفاءة

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

تم تصميم طبقة التخزين المؤقت لدينا لتعمل كممتص صدمات ضخم بين ملايين المستخدمين المتزامنين وتخزيننا الدائم. وهي تتعامل مع حمل ذروة يبلغ 1.38 مليار استعلام في الثانية (QPS)، مع مجموعات منطقية فردية تتجاوز 100 مليون استعلام في الثانية. في هذا المنشور، سنكشف النقاب عن كيفية تصميمنا لخدمة التخزين المؤقت الموحدة لتتجاوز حدود عقدة Redis® من أجل تحقيق إنتاجية هائلة، كل ذلك أثناء التعامل مع زيادة غير مسبوقة في حركة المرور بمقدار 10 أضعاف على أكبر مجموعاتنا.

إجمالي عمليات القراءة/الكتابة في ذاكرة التخزين المؤقت عبر جميع عقد التخزين المؤقت.

التوسع إلى ما وراء حدود الصناعة لتلبية الطلبات المتزايدة باستمرار

في Roblox، تعتمد خدمة التخزين المؤقت لدينا على تقنية Redis®، ويمكن لمجموعة Redis® واحدة دعم ما يصل إلى 1000 عقدة. ومع ذلك، فإن الحد التجريبي والمقبول في الصناعة أقل بكثير — حوالي 400-500 عقدة.1 ويرجع ذلك إلى بروتوكول Gossip اللامركزي في Redis®، والذي يستخدم الاتصال بين العقد لمشاركة الحالة الصحية والحالة وتعيين الشرائح. في المجموعات التي يزيد حجمها عن بضع مئات من العقد، تبدأ الاتصالات الناتجة عن بروتوكول Gossip في استهلاك موارد كبيرة من وحدة المعالجة المركزية والشبكة. يجب أن تعالج كل عقدة تحديثات الحالة الواردة من عدد متزايد باستمرار من الأقران، مما يسلب الموارد من المهمة الأساسية المتمثلة في تقديم البيانات بزمن انتقال منخفض. يمكن أن تؤدي هذه الأعباء الإضافية على مستوى التحكم إلى عدم الاستقرار وأداء غير متوقع، وهذا هو السبب في أن مزودي الخدمات السحابية المدارة يفرضون حدودًا على العقد. إنه سقف عملي لا يمكن تجاوزه دون المساس بالموثوقية.

هذا الحد العملي للمجموعة الواحدة لا يكفي لدعم منصة تعمل على نطاق Roblox، حيث تطلبت أكبر خدمة خلفية أكثر من 100 مليون QPS من إحدى مجموعات Redis® المنطقية لدينا في ذروة الاستخدام، بعد أن كانت 10 ملايين خلال ثلاثة أشهر.

لقد اعتمدنا بنية اتحادية للتغلب على هذا القيد المعماري، حيث وضعنا وكيل عكسي للعميل أمام عدة مجموعات Redis® أصغر حجمًا ومستقلة. نستخدم حدًا أقصى يبلغ 400 عقدة لكل مجموعة لضمان أداء يمكن التنبؤ به. 

من منظور آلاف التطبيقات والخدمات لدينا، يقدم الوكيل العكسي للعميل هذه المجموعات المتباينة كخدمة تخزين مؤقت فريدة وموحدة وقابلة للتوسع. يتيح لنا هذا الاتحاد التوسع أفقيًا بشكل شبه غير محدود بمجرد إضافة المزيد من المجموعات إلى الاتحاد، متجاوزين قيود بروتوكول Gossip تمامًا. اليوم، يتكون أكبر نشر للتخزين المؤقت لدينا من أكثر من 6000 عقدة Redis®، مدعومة بأكثر من 15 مجموعة Redis® مستقلة — وهو نطاق لم يكن ممكنًا إلا بفضل هذا النموذج الاتحادي.

رسم تخطيطي عالي المستوى للبنية الموحدة.

عملية الترحيل ثلاثية المراحل

كان الانتقال من الإعداد التقليدي إلى بنية موحدة مع إدارة مئات من مجموعات الإنتاج النشطة مهمة كبيرة. في نهاية عام 2024، كانت العديد من هذه المجموعات قد اقتربت بالفعل من الحد الأقصى البالغ 400 عقدة، مما جعل الانتقال إلى نموذج ذي سعة أعلى أمراً ملحاً. كان التحدي الرئيسي هو أن مثيلات Redis® القياسية تعمل بشكل منفصل ولا تدرك وجود المجموعات الأخرى، مما استلزم طريقة مخصصة لنسخ البيانات أثناء النقل.

لحل هذه المشكلة، قمنا بتطوير مسار ترحيل شفاف من ثلاث مراحل مصمم لترحيل الخدمات دون أي تدخل من العملاء أو تغييرات على جانب التطبيق.

سير عمل الترحيل

  1. الكتابة المزدوجة: قمنا بتكوين الوكيل العكسي للعميل لإجراء عمليات كتابة مزدوجة، وإرسال البيانات الواردة إلى كل من المجموعة الأصلية والوجهة الاتحادية الجديدة في وقت واحد.
  2. التكافؤ وتبديل القراءة: بمجرد أن قامت عملية الكتابة المزدوجة بتعبئة المجموعة الجديدة ببيانات متطابقة، ونظرًا لأن جميع البيانات مقيدة بمدة صلاحية (TTL)، قمنا بنقل حركة مرور القراءة من المجموعة القديمة إلى البنية الاتحادية الجديدة.
  3. إيقاف التشغيل: بعد التأكد من استقرار المجموعة الجديدة، أوقفنا جميع عمليات الكتابة إلى المجموعة الأصلية وقمنا بإيقاف تشغيلها.

نجحنا في نقل خدماتنا الأكثر أهمية إلى نموذج موحد يدعم أكثر من 6000 عقدة، وهو ما يتجاوز بكثير حدود المجموعة الفردية Redis®. 

التعامل مع النمو الهائل لـ Grow a Garden

ابتداءً من أبريل 2025، واجهنا تحديًا في السعة لم يواجهه سوى عدد قليل من الخدمات. كان الدافع وراء ذلك هو النجاح الهائل الذي حققته لعبة Grow a Garden. في غضون أسابيع قليلة من إطلاقها، بدأت لعبة Grow a Garden في تحطيم ليس فقط أرقام Roblox القياسية، بل وأرقام صناعة الألعاب القياسية على الإطلاق من حيث عدد المستخدمين المتزامنين (CCU). في غضون ثلاثة أشهر فقط، تجاوز جمهور اللعبة رقمنا القياسي السابق لعدد المستخدمين المتزامنين (CCU) للعبة واحدة البالغ 2.8 مليون لاعب، ليصل إلى ذروة تجاوزت 21 مليون لاعب. أدى هذا النمو الهائل إلى زيادة حركة المرور بمقدار 10 أضعاف على أكبر مجموعة Redis® لدينا، وزيادة حركة المرور بمقدار 3 أضعاف على التخزين المؤقت بشكل عام.

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

تحسين الكفاءة أثناء الطفرة

أولاً، كان علينا تحديد الاختناقات الأكثر تأثيرًا في نظامنا حتى نتمكن من إعطاء الأولوية لأعمال التحسين. يعمل التخزين المؤقت في Roblox على مجموعتين مختلفتين من الأجهزة: واحدة لعقد الخلفية Redis® والأخرى لـ Envoy. تعتمد أسطول Redis® لدينا بشكل أساسي على الذاكرة، بينما يعتمد وكيل العميل على الحوسبة. 

بالنسبة لأسطول Redis® المرتبط بالذاكرة، قمنا بتنفيذ سياسة جدولة جديدة لتحقيق توازن أفضل في استخدام الذاكرة عبر مجموعات أجهزتنا الفعلية. كما قمنا بضبط حجم الحاوية لتقليل تجزئة الذاكرة. 

لتحسين استخدام وحدة المعالجة المركزية (CPU)، قمنا بتنفيذ تحسينين رئيسيين لنظام التخزين المؤقت لدينا:

  1. التحجيم التلقائي لوكيل العميل: قمنا بتعديل سياسة التحجيم التلقائي لأسطول وكيل العميل المرتبط بالحوسبة. من خلال خفض الانحراف المسموح به عن وحدة المعالجة المركزية المستهدفة، حققنا متوسطًا أعلى لاستخدام وحدة المعالجة المركزية للمهام دون تغيير عتبة التوسع.
  2. فحوصات صحة المجموعة الداخلية: قمنا بتحسين فحوصات الصحة الداخلية للتخلص من نبضات القلب غير الضرورية، مع الحفاظ على الفاصل الزمني الأصلي للكشف مع توفير موارد الحوسبة.

أدت هذه التغييرات إلى تحسن بنسبة 10% تقريبًا في استخدام وحدة المعالجة المركزية (CPU). وأخيرًا، قمنا بدمج هذين الحملين المختلفين تمامًا في نفس مجموعة الأجهزة باستخدام عزل cgroup على مستوى الحاوية، مما أدى إلى خفض احتياجاتنا الإجمالية من السعة بنسبة 25%.

الهندسة من أجل موثوقية لا تتزعزع

ظلت الموثوقية على رأس أولوياتنا، حتى في الوقت الذي كنا نسارع فيه لتلبية الطلب الذي حطم الأرقام القياسية. 

قابلية المراقبة من البداية إلى النهاية

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

التعامل مع الأعطال

في أي نظام موزع بهذا الحجم، تحدث أحيانًا أعطال جزئية. لقد صممنا نظامنا للتعامل مع هذه الأعطال بسلاسة وتقليل تأثيرها إلى الحد الأدنى.

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

المرونة من جانب العميل

لمنع إرباك نظام التخزين المؤقت لدينا بسبب الزيادات المفاجئة في حركة المرور، قمنا بتنفيذ مرونة قوية ضد الأعطال من جانب العميل. تعمل هذه الآلية على مستوى التطبيق، مما يضمن عدم احتكار أي خدمة بمفردها لموارد التخزين المؤقت.

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

مستقبل التخزين المؤقت في Roblox

بدأت رحلة التخزين المؤقت في Roblox بمجموعات Redis® الأساسية التي يديرها كل مالك تطبيق مباشرةً، ثم انتقلت إلى مجموعات Memcached التي يديرها فريق التخزين المؤقت لدينا، ثم انتقلت أخيرًا إلى نموذج Redis® كخدمة، حيث يتم توفير مجموعة Redis® كخدمة مُدارة. على الرغم من أن هذا النموذج أثبت فعاليته الكبيرة على نطاقنا الحالي، إلا أننا ندرك محدودياته من حيث كفاءة الخدمة وعزل الموارد لمنصة ديناميكية مثل Roblox.

مع استمرار نمو المنصة، نخطط للقيام باستثمار كبير في خدمة التخزين المؤقت متعددة المستأجرين من الجيل التالي المبنية على ValKey. تم تصميم هذه البنية لتقليل التكاليف بشكل كبير من خلال مشاركة الموارد المشتركة عبر تعدد المستأجرين مع ضمان عزل البيانات والموارد والأعطال لكل مستأجر. هدفنا هو تحسين الأداء وقابلية التوسع والموثوقية والكفاءة من حيث التكلفة لبنيتنا التحتية للتخزين المؤقت بشكل كبير لتلبية متطلبات التجارب المتزايدة الضخامة على Roblox.

شكر وتقدير: 

كان هذا الإنجاز ثمرة جهد تعاوني. شكرًا لأعضاء الفريق الآخرين الذين ساهموا بشكل كبير: أوتكارش سينغ، وكارثيك راماشاندران، وفينيشا كاسيريدي، وويجي هو، وليون جاو.

1تحدد AWS عدد عقد ElasticCache بـ 500 عقدة.

*Redis هي علامة تجارية مملوكة لشركة Redis Labs Ltd. جميع الحقوق محفوظة لشركة Redis Labs Ltd.