ابتسم عندما يتأخر الرد في ألعاب الإنترنت الجماعية

ابتسم عندما يتأخر الرد في ألعاب الإنترنت الجماعية

ألعاب الإنترنت الجماعية هي بلا شك من أكثر أشكال الترفيه نمواً في السنوات الأخيرة. إذا لم تكن قمت بتجربة لعبة من هذا النوع من قبل (أشكّ في ذلك) فكل ما عليك هو أن تسأل أقرب شخص منك وسترى مقدار العشق للعبة من هذا النوع. وورلد اوف ووركرافت (World Of Warcraft) هي لعبة شهيرة من هذا النوع يلعبها أكثر من 7 ملايين لاعب و تحقق إيرادات تصل إلى العشرة مليار دولار؛ وهناك الكثير غيرها من الألعاب التي تتفاوت من ناحية الكثافة لكن تتشارك من ناحية أن العديد من اللاعبين يتشاركون بيئة اللعب. بالنسبة للاعب، فإن نجاح اللعبة يعتمد على أمور مثل التصميم وحبكة اللعبة وطريقة التحكم. الأمور الظاهرة في السطح. لكن هناك سبباً آخر في نجاح هذه الألعاب، و هو التمكن من دعم هذا العدد الكبير من اللاعبين.

لماذا يتأخر الرد في ألعاب الإنترنت الجماعية أحياناً ؟

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

scale

بدلا من اسخدام خادم واحد للرد على اللاعبين يمكن استخدام خادمين لتوفير أداء أفضل

10 خوادم على الشجرة أفضل من خادم في اليد

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

اللاعب الذهبي صاحب أكبر عدد من النقاط

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

خوارزمية اللاعب الذهبي بخادم مركزي

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

$الأكبر := أكبر مجموع نقاط لأحد اللاعبين
إذا كان مجموع نقاطي أكبر من $الأكبر نفذ التالي
    اسحب اللون الذهبي من اللاعب صاحب أكبر مجموع حاليا     
    قم بتحويل لوني إلى اللون الذهبي     
    $الأكبر = مجموع نقاطي    
انتهى الإذا

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

التزامنية مسببة للمشاكل

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

تنظيم الدخول للخوارزمية باستخدام الأقفال

هناك عدة حلول لهذه المعضلة. الحل الأسهل هو منع أكثر من خادم من تنفيذ الخوارزمية. هذا سيحل المشكلة. و يمكن تطبيق هذا الحل بتطبيق قفل (Lock) بحيث يكون حامل القفل هو الوحيد القادر على تنفيذ الخوارزمية. في هذه الحالة ستصبح الخوارزمية كالتالي:

أطلب الحصول على القفل
$الأكبر := أكبر مجموع نقاط لأحد اللاعبين
إذا كان مجموع نقاطي أكبر من $الأكبر نفذ التالي
    اسحب اللون الذهبي من اللاعب صاحب أكبر مجموع حالياً   
    قم بتحويل لوني إلى اللون الذهبي     
    $الأكبر = مجموع نقاطي     
انتهى الإذا
أطلق القفل

طابور من الخوادم ينتظرون أدوارهم لفتح القفل

ممتاز! الآن لن يكون هناك أكثر من لاعب بلون ذهبي في وقت واحد. لكن ما الذي سيحدث لأداء الخوارزمية بعد إضافة القفل؟ طلب القفل وإطلاق القفل يتطلب التواصل مع الخادم العام مما سيزيد الوقت اللازم لتنفيذ الخوارزمية بـ 4 إلى 5 ميللي ثانية. هذا ليس سيئاً. لكن المشكلة في حال أن خادماً طلب القفل في حين أن خادماً آخر في حوزته القفل. هذا سيضطر الخادم أن ينتظر حامل القفل حتى ينتهي من تنفيذ الخوارزمية. مما يعني أن وقت انتظاره سيزيد أيضاً بمقدار انتظار حامل القفل. نحن نتحدث عن لعبة إنترنت ذات كثافة لاعبين كبيرة، مما يعني أن الطلبات ستكون متسارعة. الطلبات ستنتظر بعضها البعض و ستشكل طابوراً (Queue) من الطلبات للقفل. هل سيكون هذا سيئا لأداء اللعبة؟ لمعرفة الجواب سنستعين بنظرية الطابور (Queueing Theory). الحساب في الصورة التالية يبين وقت انتظار الخادم ًذا كانت الخوارزمية (دون انتظار القفل) تستغرق 5 ميللي ثانية على حسب عدد طلبات القفل كل ثانية.

mm1queue

وقت الانتظار الذي لا يؤثر في أداء اللعبة هو 200 ميللي ثانية على حسب بعض الدراسات. لذلك، نقطة مهمة نريد معرفتها من الصورة في الأعلى هي: ما هو عدد طلبات القفل في الثانية الذي يمكن لنا دعمه. لاحظ أن وقت الانتظار يظل تحت 25 ميللي ثانية حتى 150 طلب قفل في الثانية. بعدها يزيد وقت الانتظار بشكل كبير حتى يصل لمالانهاية عند 200 طلب في الثانية. السبب هو أن 200 طلب في الثانية هو معدل أعلى من معدل تنفيذ الخوارزمية، مما يعني أن الطابور سيزيد حجمه بإطراد مؤدياً إلى أوقات انتظار فلكية. فعلياً الذي سيحدث هو فيض الدارئ (Buffer overflow) للطابور في الخادم العام مما سيجعل طلبات القفل تضيع. لكي يكون وقت الانتظار للاعب أقل من 200 ميللي ثانية يجب أن يكون عدد طلبات القفل في الثانية أقل من 190 طلب. إذا افترضنا أن كل لاعب يقوم بتنفيذ خوارزمية كسب النقاط كل 10 ثواني فإن عدد اللاعبين الذي يمكن للخادم العام دعمه هو 1900 لاعب في وقت واحد.

السرعة أم التوافق؟

قد يكون 1900 لاعب عدداً كافياً لبعض الألعاب، لكنه بالتأكيد ليس كافياً لألعاب الانترنت الكثيفة من نوع MMORPG مثلاً. هذا ما دعا كثير من مطوري خوارزميات الحوسبة الموزعة (Distributed Computing) للجوء إلى حل متطرف. هذا الحل هو أن نتعايش مع الأخطاء التي قد تحصل في اللعبة ومحاولة حلها بشكل كسول. هذا الصنف من الحلول يسمى التوافق ختاماً (Eventual Consistency). الحل في الأعلى الذي يضمن حلاً صحيحاً دائما هو من ضمن التوافق الأكيد (Strong consistency) ومعناه أن جميع الأطرف لا تخرق قواعد صحة اللعبة (لاعب واحد فقط بلون ذهبي في أي لحظة). "التوافق ختاماً" من ناحية أخرى يُضحّي بهذه الصحة المطلقة من أجل أداء أفضل ودعم عدد لاعبين أكثر.

التوافق ختاماً صحيح (تقريباً!)

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

التوافق ختامًا أم التوافق اﻷكيد؟

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

أعجبتك التدوينة؟

تفضل بتسجيل بريدك الإلكتروني حتى نرسل لك التدوينات القادمة فور نشرها في المجالات التي تهمك:

لا تقلق، نحن أيضاً لا نحب السبام 🙂

مهتم بتدوينات:

كما نرجو منك عزيزي القاريء بأن تدعمنا بنشر هذا المحتوى على الوسط المفضل لديك من الشبكات الاجتماعية بالأسفل:

فيصل نواب

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

اخر المقالات
التعليقات ( 5 )
  1. عبدالرحمن خلوف
    مايو 10, 2014 at 5:18 م
    رد

    جميل جداً أن نرى المزيد من المدونات التقنية هنا،،، موضوع استفدت منه شخصياً, استمر

    • فيصل نواب
      مايو 10, 2014 at 9:04 م
      رد

      شكرا! سعيد أن الموضوع أعجبك.

  2. Ahmed Hashem
    مايو 10, 2014 at 11:02 م
    رد

    موضوع رائع شكرا لك
    اعتقد نوع العبة هو الى راح يحدد الاسلوب المستخدم فى التوافق الى حد كبير

    • فيصل نواب
      مايو 11, 2014 at 12:36 ص
      رد

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

  3. ابتسم عندما يتأخر الرد في ألعاب الإنترنت الجماعية | Faisal Nawab
    مايو 18, 2014 at 2:10 ص
    رد

    […] يمكن الوصول لها من هذا الرابط. قراءة […]

‎اضف رد