كيفية القياس من 1 إلى 100 مستخدم

لقد مرت العديد من الشركات الناشئة بهذا: حشود من المستخدمين الجدد يسجلون كل يوم، ويكافح فريق التطوير للحفاظ على تشغيل الخدمة.

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

دعونا نحاول تصفية المعلومات وكتابة الصيغة الأساسية. سنقوم بتوسيع نطاق موقعنا الجديد لمشاركة الصور Graminsta خطوة بخطوة من 1 إلى 100 مستخدم.

دعنا نكتب الإجراءات المحددة التي يجب اتخاذها عندما يزيد الجمهور إلى 10 و100 و1000 و10 و000 شخص.

مستخدم واحد: جهاز واحد

يحتوي كل تطبيق تقريبًا، سواء كان موقعًا إلكترونيًا أو تطبيقًا للهاتف المحمول، على ثلاثة مكونات رئيسية:

  • API
  • قاعدة بيانات
  • العميل (تطبيق الهاتف المحمول نفسه أو موقع الويب)

تقوم قاعدة البيانات بتخزين البيانات المستمرة. تخدم واجهة برمجة التطبيقات (API) الطلبات حول هذه البيانات وحولها. يقوم العميل بنقل البيانات إلى المستخدم.

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

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

من الناحية النظرية، يمكننا نشرها في السحابة على مثيل DigitalOcean Droplet أو AWS EC2 واحد، كما هو موضح أدناه:
كيفية القياس من 1 إلى 100 مستخدم
ومع ذلك، إذا كان هناك أكثر من مستخدم على الموقع، فمن المنطقي دائمًا تخصيص طبقة قاعدة بيانات.

10 مستخدمين: نقل قاعدة البيانات إلى مستوى منفصل

إن تقسيم قاعدة البيانات إلى خدمات مُدارة مثل Amazon RDS أو Digital Ocean Managed Database سوف يخدمنا جيدًا لفترة طويلة. إنها أغلى قليلاً من الاستضافة الذاتية على جهاز واحد أو مثيل EC2، ولكن مع هذه الخدمات، يمكنك الحصول على الكثير من الإضافات المفيدة التي ستكون مفيدة في المستقبل: النسخ الاحتياطي متعدد المناطق، وقراءة النسخ المتماثلة، والتلقائي النسخ الاحتياطية، وأكثر من ذلك.

وهذا هو شكل النظام الآن:
كيفية القياس من 1 إلى 100 مستخدم

100 مستخدم: نقل العميل إلى مستوى منفصل

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

ولهذا السبب أحب أن أفكر في العميل بشكل منفصل عن واجهة برمجة التطبيقات (API). وهذا يجعل من السهل جدًا التفكير في التطوير لمنصات متعددة: الويب، وويب الهاتف المحمول، وiOS، وAndroid، وتطبيقات سطح المكتب، وخدمات الطرف الثالث، وما إلى ذلك. وجميعهم مجرد عملاء يستخدمون نفس واجهة برمجة التطبيقات.

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

هذا ما يبدو عليه مثل هذا النظام:

كيفية القياس من 1 إلى 100 مستخدم

1000 مستخدم: إضافة موازن التحميل

الأمور تتطلع. يقوم مستخدمو Graminsta بتحميل المزيد والمزيد من الصور. عدد التسجيلات يتزايد أيضا. يواجه خادم API الوحيد الخاص بنا صعوبة في مواكبة كل حركة المرور. بحاجة الى المزيد من الحديد!

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

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

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

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

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

كيفية القياس من 1 إلى 100 مستخدم

ملحوظة. في الوقت الحالي، يشبه نظامنا إلى حد كبير ما تقدمه شركات PaaS مثل Heroku أو Elastic Beanstalk على AWS خارج الصندوق (ولهذا السبب تحظى بشعبية كبيرة). يضع Heroku قاعدة البيانات على مضيف منفصل، ويدير موازن تحميل قابل للتوسيع التلقائي، ويسمح لك باستضافة عميل الويب بشكل منفصل عن واجهة برمجة التطبيقات (API). يعد هذا سببًا رائعًا لاستخدام Heroku في مشاريع المرحلة المبكرة أو الشركات الناشئة - حيث تحصل على جميع الخدمات الأساسية خارج الصندوق.

10 مستخدم: CDN

ربما كان علينا أن نفعل هذا منذ البداية. بدأت معالجة الطلبات وقبول الصور الجديدة في فرض ضغط كبير على خوادمنا.

في هذه المرحلة، تحتاج إلى استخدام خدمة سحابية لتخزين المحتوى الثابت - الصور ومقاطع الفيديو وغير ذلك الكثير (AWS S3 أو Digital Ocean Spaces). بشكل عام، يجب أن تتجنب واجهة برمجة التطبيقات لدينا التعامل مع أشياء مثل عرض الصور وتحميل الصور إلى الخادم.

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

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

كيفية القياس من 1 إلى 100 مستخدم

100 مستخدم: توسيع نطاق طبقة البيانات

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

وبالتعمق قليلاً في المقاييس، نرى أن وحدة المعالجة المركزية الموجودة على خادم قاعدة البيانات محملة بنسبة 80-90%. نحن في الحد.

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

التخزين المؤقت

إحدى أسهل الطرق لزيادة أداء قاعدة البيانات الخاصة بنا هي تقديم مكون جديد: طبقة ذاكرة التخزين المؤقت. الطريقة الأكثر شيوعًا للتخزين المؤقت هي مخزن سجلات القيمة الرئيسية في الذاكرة، مثل Redis أو Memcached. تحتوي معظم السحابات على إصدار مُدار من هذه الخدمات: Elasticache على AWS وMemorystore على Google Cloud.

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

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

سنقوم بتخزين النتائج من قاعدة البيانات في Redis عن طريق المفتاح user:id مع فترة صلاحية 30 ثانية. الآن، عندما يذهب شخص ما إلى الملف الشخصي لـ Mobrik، فإننا نتحقق أولاً من Redis، وإذا كانت البيانات موجودة، فإننا ببساطة ننقلها مباشرةً من Redis. الآن لا تقوم الطلبات المقدمة إلى الملف الشخصي الأكثر شيوعًا على الموقع بتحميل قاعدة البيانات الخاصة بنا.

ميزة أخرى لمعظم خدمات التخزين المؤقت هي أنها أسهل في التوسع من خوادم قواعد البيانات. يحتوي Redis على وضع Redis Cluster المدمج. على غرار موازن التحميل1، فهو يسمح لك بتوزيع ذاكرة التخزين المؤقت لـ Redis عبر أجهزة متعددة (عبر آلاف الخوادم إذا لزم الأمر).

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

قراءة النسخ المتماثلة

عندما يزداد عدد الاستعلامات في قاعدة البيانات بشكل كبير، هناك شيء آخر يمكننا القيام به وهو إضافة نسخ متماثلة للقراءة في نظام إدارة قاعدة البيانات. باستخدام الخدمات المدارة الموضحة أعلاه، يمكن القيام بذلك بنقرة واحدة. ستظل النسخة المتماثلة المقروءة حالية في قاعدة البيانات الرئيسية وتكون متاحة لعبارات SELECT.

وهذا هو نظامنا الآن:

كيفية القياس من 1 إلى 100 مستخدم

الخطوات التالية

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

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

نريد أيضًا تثبيت خدمة المراقبة والتحليلات مثل New Relic أو Datadog. سيساعدك هذا على تحديد الاستعلامات البطيئة وفهم المجالات التي تحتاج إلى تحسين. أثناء توسعنا، نريد التركيز على إيجاد الاختناقات والقضاء عليها - غالبًا باستخدام بعض الأفكار من الأقسام السابقة.

مصادر

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

الحواشي

  1. على الرغم من التشابه من حيث توزيع التحميل عبر مثيلات متعددة، فإن التنفيذ الأساسي لمجموعة Redis يختلف تمامًا عن موازن التحميل. [يعود]

كيفية القياس من 1 إلى 100 مستخدم

المصدر: www.habr.com

إضافة تعليق