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

Skip to content

عودة Roblox إلى الخدمة

ابتداءً من 28 أكتوبر وحتى حل المشكلة تمامًا في 31 أكتوبر، تعرضت Roblox لانقطاع في الخدمة استمر لمدة 73 ساعة.¹ يستخدم 50 مليون لاعب Roblox بانتظام كل يوم، ولتوفير التجربة التي يتوقعها لاعبونا، فإن نطاق عملنا يشمل مئات الخدمات الداخلية عبر الإنترنت. وكما هو الحال مع أي خدمة واسعة النطاق، فإننا نواجه انقطاعات في الخدمة من وقت لآخر، ولكن طول مدة هذا الانقطاع يجعله جديرًا بالملاحظة بشكل خاص. نعتذر بصدق لمجتمعنا عن هذا الانقطاع.

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

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

ملخص الانقطاع

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

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

مقدمة: بيئة الكلستر لدينا و HashiStack

تعمل البنية التحتية الأساسية لـ Roblox في مراكز بيانات Roblox. نقوم بنشر وإدارة أجهزتنا الخاصة، بالإضافة إلى أنظمة الحوسبة والتخزين والشبكات الخاصة بنا فوق تلك الأجهزة. حجم نشرنا كبير، حيث يضم أكثر من 18,000 خادم و170,000 حاوية.

من أجل تشغيل آلاف الخوادم عبر مواقع متعددة، نستفيد من مجموعة تقنيات تُعرف عمومًا باسم "HashiStack". Nomad وConsul وVault هي التقنيات التي نستخدمها لإدارة الخوادم والخدمات في جميع أنحاء العالم، والتي تسمح لنا بتنسيق الحاويات التي تدعم خدمات Roblox.

يُستخدم Nomad لجدولة العمل. فهو يحدد الحاويات التي ستعمل على العقد المحددة والمنافذ التي يمكن الوصول إليها. كما يتحقق من سلامة الحاويات. يتم ترحيل جميع هذه البيانات إلى سجل الخدمات، وهو قاعدة بيانات تضم مجموعات IP:Port. تستخدم خدمات Roblox سجل الخدمات للعثور على بعضها البعض حتى تتمكن من التواصل. تسمى هذه العملية "اكتشاف الخدمة". نستخدم Consul لاكتشاف الخدمات وفحوصات الحالة وقفل الجلسات (لأنظمة HA المبنية فوقها) وكمخزن KV.

يتم نشر Consul كمجموعة من الأجهزة في دورين. "المصوتون" (5 أجهزة) يحتفظون بحالة المجموعة بشكل رسمي؛ "غير المصوتين" (5 أجهزة إضافية) هم نسخ متماثلة للقراءة فقط تساعد في توسيع نطاق طلبات القراءة. في أي وقت، يتم انتخاب أحد المصوتين من قبل المجموعة كقائد. القائد مسؤول عن نسخ البيانات إلى المصوتين الآخرين وتحديد ما إذا كانت البيانات المكتوبة قد تم تثبيتها بالكامل.  يستخدم Consul خوارزمية تسمى Raft لانتخاب القائد وتوزيع الحالة عبر المجموعة بطريقة تضمن موافقة كل عقدة في المجموعة على التحديثات. ليس من غير المألوف أن يتغير القائد عبر انتخاب القائد عدة مرات خلال يوم معين.

فيما يلي لقطة شاشة حديثة للوحة معلومات Consul في Roblox بعد الحادث. تظهر العديد من المقاييس التشغيلية الرئيسية المشار إليها في منشور المدونة هذا عند مستويات طبيعية. على سبيل المثال، يعتبر وقت تطبيق KV طبيعيًا إذا كان أقل من 300 مللي ثانية، وهو 30.6 مللي ثانية في هذه اللحظة. تواصل القائد في Consul مع الخوادم الأخرى في المجموعة خلال آخر 32 مللي ثانية، وهو أمر حديث جدًا.

1. العمليات العادية للقنصل في Roblox

في الأشهر التي سبقت حادثة أكتوبر، قامت Roblox بالترقية من Consul 1.9 إلى Consul 1.10 للاستفادة من ميزة البث الجديدة. تم تصميم ميزة البث هذه لتقليل استهلاك وحدة المعالجة المركزية وعرض النطاق الترددي للشبكة بشكل كبير، وهو ما يلزم لتوزيع التحديثات عبر مجموعات واسعة النطاق مثل تلك الموجودة في Roblox.

الاكتشاف الأولي (28/10 13:37)

في بعد ظهر يوم 28 أكتوبر، انخفض أداء Vault وكان هناك خادم Consul واحد يعاني من حمل عالٍ على وحدة المعالجة المركزية. بدأ مهندسو Roblox في التحقيق. في هذه المرحلة، لم يتأثر اللاعبون.

التقييم الأولي (28 أكتوبر 13:37 – 29 أكتوبر 02:00)

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

حتى مع الأجهزة الجديدة، استمر أداء مجموعة Consul في التدهور. في الساعة 16:35، انخفض عدد اللاعبين المتصلين إلى 50٪ من المعدل الطبيعي.

2. CCU خلال 16:35 PST Player Drop

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

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

نظرًا لخطورة الحادث، قرر الفريق استبدال جميع العقد في مجموعة Consul بأجهزة جديدة أكثر قوة. كانت هذه الأجهزة الجديدة تحتوي على 128 نواة (زيادة بمقدار الضعف) وأقراص SSD NVME أحدث وأسرع. بحلول الساعة 19:00، قام الفريق بترحيل معظم المجموعة إلى الأجهزة الجديدة، لكن المجموعة لم تكن تعمل بشكل سليم بعد. كانت المجموعة تشير إلى أن غالبية العقد لم تكن قادرة على مواكبة عمليات الكتابة، وكان زمن الوصول في الشريحة الخمسين لعمليات الكتابة في KV لا يزال حوالي ثانيتين بدلاً من 300 مللي ثانية أو أقل كما هو معتاد.

محاولة إعادة الخدمة رقم 1 (29/10 02:00 – 04:00)

فشلت المحاولتان الأوليان لإعادة مجموعة Consul إلى حالة سليمة. كنا لا نزال نلاحظ ارتفاع زمن انتقال عمليات الكتابة في KV بالإضافة إلى ظهور أعراض جديدة غير مبررة لم نتمكن من تفسيرها: كان قائد Consul غير متزامن بشكل منتظم مع المصوتين الآخرين. 

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

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

سارت عملية إعادة الضبط بسلاسة، وبدت المقاييس جيدة في البداية. عندما أزلنا حظر iptables، عاد حمل اكتشاف الخدمة وفحص الحالة من الخدمات الداخلية كما هو متوقع. ومع ذلك، بدأ أداء Consul في التدهور مرة أخرى، وفي النهاية عدنا إلى حيث بدأنا: عاد النسبة المئوية 50 لعمليات الكتابة KV إلى 2 ثانية. بدأت الخدمات التي تعتمد على Consul في تصنيف نفسها على أنها "غير سليمة"، وفي النهاية، عاد النظام إلى الحالة المشكوك فيها التي أصبحت مألوفة الآن. كانت الساعة الآن 04:00. كان من الواضح أن هناك شيئًا ما في الحمل الذي نضعه على Consul يتسبب في مشاكل، وبعد مرور أكثر من 14 ساعة على وقوع الحادث، ما زلنا لا نعرف ما هو.

محاولة إعادة الخدمة رقم 2 (29/10 الساعة 04:00 – 30/10 الساعة 02:00)

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

قرر فريق الهندسة تقليل استخدام Consul ثم إعادة إدخاله بعناية وبشكل منهجي. لضمان أن يكون لدينا نقطة انطلاق نظيفة، قمنا أيضًا بحظر حركة المرور الخارجية المتبقية. قمنا بتجميع قائمة شاملة بالخدمات التي تستخدم Consul وقمنا بتطبيق تغييرات في التكوين لتعطيل جميع الاستخدامات غير الضرورية. استغرقت هذه العملية عدة ساعات بسبب التنوع الكبير في الأنظمة وأنواع تغييرات التكوين المستهدفة. تم تقليص خدمات Roblox التي عادةً ما كان يعمل بها مئات المثيلات إلى أرقام مفردة. تم تقليل وتيرة فحص الحالة من 60 ثانية إلى 10 دقائق لمنح المجموعة مساحة إضافية للتنفس. في الساعة 16:00 من يوم 29 أكتوبر، بعد أكثر من 24 ساعة من بدء الانقطاع، بدأ الفريق محاولته الثانية لإعادة Roblox إلى العمل. مرة أخرى، بدت المرحلة الأولية من محاولة إعادة التشغيل هذه جيدة، ولكن بحلول الساعة 02:00 من يوم 30 أكتوبر، كان Consul مرة أخرى في حالة غير سليمة، هذه المرة مع حمل أقل بكثير من خدمات Roblox التي تعتمد عليه.

في هذه المرحلة، كان من الواضح أن الاستخدام العام لـ Consul لم يكن العامل الوحيد الذي ساهم في تدهور الأداء الذي لاحظناه لأول مرة في يوم 28. وبناءً على هذا الإدراك، غير الفريق مساره مرة أخرى. بدلاً من النظر إلى Consul من منظور خدمات Roblox التي تعتمد عليه، بدأ الفريق في البحث عن أدلة داخلية في Consul.

البحث في التنازع (30 أكتوبر 02:00 – 30 أكتوبر 12:00)

على مدار الساعات العشر التالية، تعمق فريق الهندسة في سجلات التصحيح ومقاييس مستوى نظام التشغيل. أظهرت هذه البيانات أن عمليات الكتابة في Consul KV يتم حظرها لفترات طويلة. بعبارة أخرى، "التنازع". لم يكن سبب التنازع واضحًا على الفور، لكن إحدى النظريات كانت أن الانتقال من خوادم ذات 64 نواة إلى خوادم ذات 128 نواة في وقت مبكر من الانقطاع ربما أدى إلى تفاقم المشكلة. بعد الاطلاع على بيانات htop وبيانات تصحيح الأداء الموضحة في لقطات الشاشة أدناه، خلص الفريق إلى أنه من الأفضل العودة إلى خوادم ذات 64 نواة مشابهة لتلك المستخدمة قبل الانقطاع. بدأ الفريق في تجهيز الأجهزة: تم تثبيت Consul، وتدقيق تكوينات نظام التشغيل ثلاث مرات، وتجهيز الأجهزة للخدمة بأكبر قدر ممكن من التفصيل. ثم قام الفريق بتحويل مجموعة Consul مرة أخرى إلى خوادم ذات 64 نواة CPU، لكن هذا التغيير لم يساعد. كانت هذه محاولتنا الرابعة لتشخيص السبب الجذري للحادث.

3. ثم قمنا بعرض ذلك باستخدام تقرير الأداء كما هو موضح أعلاه. تم قضاء معظم الوقت في أقفال دوران النواة عبر مسار كود الاشتراك في البث.
4. HTOP يعرض استخدام وحدة المعالجة المركزية عبر 128 نواة.

تم العثور على الأسباب الجذرية (30/10 12:00 – 30/10 20:00)

قبل عدة أشهر، قمنا بتفعيل ميزة بث جديدة في Consul على مجموعة فرعية من خدماتنا. هذه الميزة، المصممة لتقليل استخدام وحدة المعالجة المركزية (CPU) وعرض النطاق الترددي للشبكة في مجموعة Consul، عملت كما هو متوقع، لذا قمنا خلال الأشهر القليلة التالية بتفعيل الميزة تدريجيًا على المزيد من خدماتنا الخلفية. في 27 أكتوبر الساعة 14:00، أي قبل يوم واحد من انقطاع الخدمة، قمنا بتفعيل هذه الميزة على خدمة خلفية مسؤولة عن توجيه حركة المرور. كجزء من هذا النشر، ومن أجل الاستعداد لزيادة حركة المرور التي نشهدها عادةً في نهاية العام، قمنا أيضًا بزيادة عدد العقد التي تدعم توجيه حركة المرور بنسبة 50٪. كان النظام قد عمل بشكل جيد مع البث المباشر عند هذا المستوى لمدة يوم واحد قبل بدء الحادث، لذا لم يكن من الواضح في البداية سبب تغير أدائه. ومع ذلك، من خلال تحليل تقارير الأداء والرسوم البيانية من خوادم Consul، رأينا أدلة على أن مسارات كود البث هي المسؤولة عن التنازع الذي تسبب في ارتفاع استخدام وحدة المعالجة المركزية. قمنا بتعطيل ميزة البث لجميع أنظمة Consul، بما في ذلك العقد المسؤولة عن توجيه حركة المرور. انتهى نشر تغيير التكوين في الساعة 15:51، وفي ذلك الوقت انخفضت النسبة المئوية الخمسين لعمليات الكتابة في Consul KV إلى 300 مللي ثانية. حققنا أخيرًا اختراقًا.

لماذا كان البث يمثل مشكلة؟ أوضحت HashiCorp أنه على الرغم من أن البث كان أكثر كفاءة بشكل عام، إلا أنه استخدم عناصر تحكم في التزامن (قنوات Go) أقل في تنفيذه مقارنة بالاستقصاء الطويل. في ظل الحمل العالي جدًا – على وجه التحديد، كل من حمل القراءة العالي جدًا وحمل الكتابة العالي جدًا – يؤدي تصميم البث إلى تفاقم مقدار التنازع على قناة Go واحدة، مما يتسبب في الحجب أثناء عمليات الكتابة، مما يجعله أقل كفاءة بشكل ملحوظ. وقد أوضح هذا السلوك أيضًا تأثير الخوادم ذات عدد النوى الأعلى: كانت تلك الخوادم عبارة عن بنى ثنائية المقبس مع نموذج ذاكرة NUMA. وبالتالي، ازداد التنازع الإضافي على الموارد المشتركة سوءًا في ظل هذه البنية. ومن خلال إيقاف تشغيل البث، قمنا بتحسين حالة مجموعة Consul بشكل كبير.

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

ولكن ما الذي كان يحدث مع القادة البطيئين؟ لم نكتشف ذلك أثناء الحادث، لكن مهندسي HashiCorp حددوا السبب الجذري في الأيام التي أعقبت الانقطاع. يستخدم Consul مكتبة استمرارية مفتوحة المصدر شائعة تسمى BoltDB لتخزين سجلات Raft. لا تُستخدم لتخزين الحالة الحالية داخل Consul، بل كسجل متجدد للعمليات التي يتم تطبيقها. لمنع BoltDB من النمو إلى ما لا نهاية، يقوم Consul بانتظام بعمل لقطات. تكتب عملية اللقطة الحالة الحالية لـ Consul على القرص ثم تحذف أقدم إدخالات السجل من BoltDB. 

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

استعادة خدمة التخزين المؤقت (30 أكتوبر 20:00 – 31 أكتوبر 05:00)

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

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

واجهت عملية إعادة نشر ذاكرة التخزين المؤقت سلسلة من المشكلات: 

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

عمل الفريق طوال الليل لتحديد هذه المشكلات ومعالجتها، وضمان نشر أنظمة التخزين المؤقت بشكل صحيح، والتحقق من صحتها. في الساعة 05:00 من يوم 31 أكتوبر، بعد 61 ساعة من بدء الانقطاع، أصبح لدينا مجموعة Consul سليمة ونظام تخزين مؤقت سليم. كنا جاهزين لتشغيل بقية Roblox.

عودة اللاعبين (31 أكتوبر 05:00 – 31 أكتوبر 16:00)

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

مع وجود ذاكرات تخزين مؤقتة باردة ونظام كنا لا نزال غير متأكدين منه، لم نرغب في تدفق حركة مرور قد يعيد النظام إلى حالة عدم الاستقرار. لتجنب هذا التدفق، استخدمنا توجيه DNS لإدارة عدد اللاعبين الذين يمكنهم الوصول إلى Roblox. سمح لنا ذلك بالسماح بنسبة معينة من اللاعبين المختارين عشوائياً بالدخول بينما استمر توجيه الآخرين إلى صفحة الصيانة الثابتة الخاصة بنا. في كل مرة كنا نزيد فيها النسبة المئوية، كنا نتحقق من حمل قاعدة البيانات وأداء ذاكرة التخزين المؤقت واستقرار النظام بشكل عام. استمر العمل طوال اليوم، مع زيادة الوصول بزيادات تبلغ حوالي 10٪. استمتعنا برؤية بعض لاعبينا الأكثر تفانيًا يكتشفون مخطط توجيه DNS الخاص بنا ويبدأون في تبادل هذه المعلومات على Twitter حتى يتمكنوا من الحصول على وصول "مبكر" مع إعادة تشغيل الخدمة. في الساعة 16:45 من يوم الأحد، بعد 73 ساعة من بدء الانقطاع، تم منح 100٪ من اللاعبين حق الوصول وأصبح Roblox يعمل بكامل طاقته.

تحليلات وتغييرات إضافية ناتجة عن الانقطاع

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

كشفت التحليلات الإضافية لمشكلة "الرائد البطيء" أيضًا عن السبب الرئيسي لكتابة بيانات Raft التي تستغرق ثانيتين ومشكلات اتساق المجموعة. درس المهندسون الرسوم البيانية مثل تلك الموضحة أدناه لفهم أفضل للآليات الداخلية لـ BoltDB.

5. تحليل عمليات قائمة الحرية في BoltDB.
كما ذكرنا سابقًا، يستخدم Consul مكتبة استمرارية تسمى BoltDB لتخزين بيانات سجل Raft. وبسبب نمط استخدام معين نشأ أثناء الحادث، أصبحت عمليات الكتابة التي تبلغ 16 كيلوبايت أكبر بكثير. يمكنك رؤية المشكلة موضحة في لقطات الشاشة التالية:
6. إحصائيات BoldDB التفصيلية المستخدمة في التحليل.

يخبرنا ناتج الأمر السابق بعدة أمور:

  • مخزن السجلات هذا الذي تبلغ سعته 4.2 جيجابايت لا يخزن سوى 489 ميجابايت من البيانات الفعلية (بما في ذلك جميع مكونات الفهرس الداخلية). أما 3.8 جيجابايت فهي مساحة "فارغة".
  • تبلغ مساحة قائمة المساحات الحرة 7.8 ميجابايت لأنها تحتوي على ما يقرب من مليون معرف صفحة حرة.

وهذا يعني أنه لكل إضافة إلى السجل (كل عملية كتابة Raft بعد بعض عمليات التجميع)، يتم أيضًا كتابة قائمة حرة جديدة بحجم 7.8 ميجابايت على القرص، على الرغم من أن حجم البيانات الأولية الفعلية التي تمت إضافتها كان 16 كيلوبايت أو أقل. 

كما أدى الضغط العكسي على هذه العمليات إلى امتلاء مخازن TCP المؤقتة وساهم في زيادة وقت الكتابة إلى 2-3 ثوانٍ على القادة غير السليمين. توضح الصورة أدناه البحث الذي أجري حول TCP Zero Windows أثناء الحادث.

7. بحث حول نوافذ TCP الصفرية. عندما يبدأ مخزن مؤقت مستقبل TCP في الامتلاء، يمكنه تقليل نافذة الاستقبال الخاصة به. وإذا امتلأ، يمكنه تقليل النافذة إلى الصفر، مما يُعلم مرسل TCP بالتوقف عن الإرسال.التعليق

قامت HashiCorp و Roblox بتطوير ونشر عملية باستخدام أدوات BoltDB الحالية لـ "ضغط" قاعدة البيانات، مما أدى إلى حل مشكلات الأداء.

التحسينات الأخيرة والخطوات المستقبلية

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

القائمة الكاملة للتحسينات التي تم إنجازها وتلك التي لا تزال قيد التنفيذ طويلة جدًا ومفصلة جدًا بحيث لا يمكن إدراجها في هذا المقال، ولكن إليكم النقاط الرئيسية:

تحسينات القياس عن بُعد

كانت هناك علاقة تبعية دائرية بين أنظمة القياس عن بُعد لدينا و Consul، مما يعني أنه عندما كان Consul في حالة سيئة، كنا نفتقر إلى بيانات القياس عن بُعد التي كانت ستسهل علينا تحديد المشكلة. لقد أزلنا هذه العلاقة التبعية الدائرية. لم تعد أنظمة القياس عن بُعد لدينا تعتمد على الأنظمة التي تم تكوينها لمراقبتها.

لقد قمنا بتوسيع نطاق أنظمة القياس عن بُعد لدينا لتوفير رؤية أفضل لأداء Consul و BoltDB. نحن نتلقى الآن تنبيهات محددة للغاية إذا كانت هناك أي علامات تشير إلى أن النظام يقترب من الحالة التي تسببت في هذا الانقطاع. كما قمنا بتوسيع نطاق أنظمة القياس عن بُعد لدينا لتوفير رؤية أوضح لأنماط حركة المرور بين خدمات Roblox و Consul. وقد ساعدتنا هذه الرؤية الإضافية لسلوك وأداء نظامنا على مستويات متعددة بالفعل أثناء عمليات ترقية النظام وجلسات تصحيح الأخطاء.

التوسع في مناطق توفر ومراكز بيانات متعددة

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

ترقيات Consul والتجزئة

لا تزال Roblox تنمو بسرعة، لذا حتى مع وجود مجموعات Consul متعددة، نرغب في تقليل الحمل الذي نضعه على Consul. لقد راجعنا كيفية استخدام خدماتنا لمخزن KV وفحوصات الحالة في Consul، وقمنا بتقسيم بعض الخدمات الحيوية إلى مجموعات مخصصة لها، مما أدى إلى تقليل الحمل على مجموعة Consul المركزية لدينا إلى مستوى أكثر أمانًا.

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

اكتشفنا كمية كبيرة من بيانات KV القديمة. أدى حذف هذه البيانات القديمة إلى تحسين أداء Consul.

نحن نعمل عن كثب مع HashiCorp لنشر إصدار جديد من Consul يستبدل BoltDB بخلف له يسمى bbolt لا يعاني من نفس مشكلة النمو غير المحدود لقائمة العناصر الحرة. لقد أرجأنا هذا الجهد عمدًا إلى العام الجديد لتجنب إجراء ترقية معقدة خلال ذروة حركة المرور في نهاية العام. يجري اختبار الترقية الآن وستكتمل في الربع الأول.

تحسينات على إجراءات التمهيد وإدارة التكوين

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

لقد عملنا مع HashiCorp لتحديد العديد من التحسينات على Nomad التي ستسهل علينا تشغيل المهام الكبيرة بعد فترة طويلة من عدم التوفر. سيتم نشر هذه التحسينات كجزء من ترقية Nomad التالية، المقرر إجراؤها في وقت لاحق من هذا الشهر.

لقد قمنا بتطوير ونشر آليات لتسريع تغييرات تكوين الأجهزة.

إعادة إدخال البث

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

ملاحظة حول السحابة العامة

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

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

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

استقرار النظام منذ انقطاع الخدمة

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

خاتمة

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

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

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

شكرًا لكم مرة أخرى. 

¹ ملاحظة: جميع التواريخ والأوقات الواردة في هذه المدونة هي بتوقيت المحيط الهادئ القياسي (PST).