كيفية التوسع من 1 إلى 100000 مستخدم

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

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

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

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

مستخدم واحد: سيارة واحدة


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

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

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

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

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

نظريا ، يمكننا نشره في السحابة على مثيل واحد من DigitalOcean Droplet أو AWS EC2 ، كما هو موضح أدناه:

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

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


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

هكذا يبدو النظام الآن:

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


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

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

على سبيل المثال ، يطلب مستخدمونا الآن غالبًا إصدار تطبيق جوال. يسهل الفصل بين كيانات العملاء وواجهات برمجة التطبيقات.

إليك ما يبدو عليه النظام:



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


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

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

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

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

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

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


. , PaaS, Heroku Elastic Beanstalk AWS ( ). Heroku , - API. , Heroku — .

10 000 : CDN


ربما كان يجب أن يتم ذلك منذ البداية. بدأت معالجة الطلبات والتقاط صور جديدة في تحميل خوادمنا أكثر من اللازم.

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

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

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



100،000 مستخدم: قياس مستوى البيانات


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

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

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

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


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

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

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

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

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

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

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


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

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



مزيد من الإجراءات


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

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

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

المصادر


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

الحواشي


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



Source: https://habr.com/ru/post/undefined/


All Articles