أنا كايل ماكورميك ، طالبة جامعية صاعدة في معهد Worcester Polytechnic ، وقد أنهيت للتو تدريبًا صيفيًا لمدة 11 أسبوعًا في فريق edX's Mobile. خلال الفترة التي أمضيتها في الفريق ، ركزت بشكل أساسي على العمل الخلفي المتعلق بالأداء. في هذا المنشور ، سأتحدث عن أحد المشروعين اللذين قضيت فيهما معظم الوقت.
ذاكرة التخزين المؤقت للبيانات الوصفية للدورة التدريبية
كانت إحدى أولى المشكلات التي تناولتها هي معرفة سبب المكالمات إلى فريقنا واجهة برمجة تطبيقات تسجيل دورة المستخدم استغرقت نقطة النهاية ، التي تُستخدم لعرض الشاشة الرئيسية في تطبيقنا للجوّال ، أكثر من ثانية للرد. تقوم نقطة النهاية ببساطة بإرجاع قائمة الدورات التي تم تسجيل المستخدم فيها ، إلى جانب بعض البيانات الوصفية الأساسية للدورة التدريبية (الاسم والجامعة وتاريخ البدء وما إلى ذلك) ، لذلك كان من المدهش أن يستغرق الأمر أكثر من بضع مئات من الألف من الثانية. لقد بدأت تحقيقي من خلال السير في الكود الذي يحسب قائمة التسجيل ، باستخدام بيينسترومنت للقيام بالتنميط.
من أول الأشياء التي لاحظتها أنه بالنسبة لكل تسجيل في الدورة ، تم تحميل البيانات الوصفية للدورة من MongoDB ثلاث مرات منفصلة (مرتين في مكالمات التسجيل مرة أثناء التسلسل) ولم يتم تخزينه مؤقتًا بين استدعاءات نقطة النهاية. كان لدي شك في أن هذا هو سبب مشاكل أداء نقطة النهاية ، والتي أكدتها باستخدام أداة "تتبع الأشعة السينية" من NewRelic.

كما ترى من التتبع الموضح أعلاه ، الوظيفة modulestore / مختلط، الذي يقوم بتحميل المناهج التعليمية من MongoDB ، كان يستهلك 90٪ من وقت الاستجابة. هذا يعني أن هناك طريقتين لتحسين نقطة النهاية: make get_course بشكل أسرع ، أو قلل عدد المكالمات إليها عن طريق التخزين المؤقت للبيانات التي يتم إرجاعها بواسطة get_course. في حين أن الأول هو بالتأكيد شيء يجب القيام به ، إلا أنها مهمة تتطلب تغييرات كبيرة في رمز النظام الأساسي الأساسي. نظرًا لأن حل التخزين المؤقت أسهل في التنفيذ - فهو مجرد طبقة فوق get_course اتصال - اخترت متابعة الحل الأخير. بالإضافة إلى ذلك ، نظرًا لأن التخزين المؤقت يعمل بين الطلبات ، فهو تحسين له فوائد حتى لو get_course هو الأمثل.
لتخزين البيانات الوصفية للدورة التدريبية مؤقتًا ، قمت بإنشاء نموذج Django يسمى نظرة عامة. أول مرة يتم فيها طلب البيانات الوصفية للدورة التدريبية ، get_course يسمى مثيل نظرة عامة يتم إنشاؤه من قيمة الإرجاع الخاصة به ، ويتم حفظ المثيل في MySQL. سيقوم الطلب التالي للبيانات الوصفية للدورة التدريبية بتحميل ملف نظرة عامة المثال ، الذي يتطلب استعلام MySQL واحدًا فقط (على عكس استعلامات 1-4 MongoDB التي يتم تنفيذها لكل استدعاء لـ get_course). عندما يتم تحديث دورة في edX Studio ، فإن المقابل نظرة عامة تم مسح المثيل ، مما يفرض الطلب التالي لجلب البيانات الوصفية المحدثة عن طريق الاتصال get_course مرة أخرى.
لقد قمت بتحديث نقطة نهاية واجهة برمجة تطبيقات تسجيل دورة مستخدم الأجهزة المحمولة لاستخدام نظام التخزين المؤقت هذا (رقم العلاقات العامة 8484) ، وأجرى اختبار الحمل باستخدام Locust.io للتأكد من وجود تحسن في الأداء. من خلال النظر في بيانات الإنتاج على NewRelic في وقت قريب من إصدار الكود المحدث ، يكون تأثير الأداء واضحًا بشكل لافت للنظر.

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

يوضح الرسم البياني أعلاه أزمن الاستجابة الفعلي للوحة معلومات الطالب edX المستندة إلى الويب بالميلي ثانية. تم تحديث لوحة القيادة لاستخدام التخزين المؤقت للبيانات الوصفية في 17 يوليو. انخفض متوسط وقت الاستجابة من 600-800 مللي ثانية إلى ~ 250 مللي ثانية.
بالإضافة إلى حالتي الاستخدام هاتين ، يمكن الاستفادة من نظام التخزين المؤقت في أي سيناريو تتطلب البيانات الوصفية الأساسية للدورة التدريبية الحيادية للمستخدم. على سبيل المثال ، قام موظف آخر في edX مؤخرًا بتحديث واجهة برمجة تطبيقات التسجيل العامة لدينا لاستخدامها نظرة عامةبدلا من الاتصال get_course (رقم العلاقات العامة 8927) ، مما أدى إلى انخفاض 10x في زمن الاستجابة المئوية 95 لـ عرض قائمة التسجيل نقطة النهاية.
خاتمة
كما ذكر زميلي المتدرب بن في مشاركة مدونته، يتألق برنامج التدريب الداخلي في edX حقًا في كيفية تضمين المتدربين في فرق هندسة البرمجيات الحقيقية ، ومعاملتهم مثل الموظفين بدوام كامل ومنحهم مشاريع مؤثرة للعمل عليها. نظرًا لأنني لم أعمل من قبل في مشروع بهذا الحجم وعدد المساهمين ، فقد تعلمت قدرًا لا يصدق. على الرغم من أن فترة ولايتي هنا قد انتهت ، إلا أنني آمل أن أبقى مشاركًا في مجتمع Open edX الرائع. أخيرًا ، أود أن أشكر Nimisha و Chris و Kishore و Adam و Dave وبقية فريق edX على تجربة تدريب لا تضاهى!
![]()