حول المحتوى:
شرح التوسع الأفقي مقابل التوسع العمودي وكيف تبني بنية قادرة على خدمة ملايين المستخدمين.
في عالم اليوم، التطبيقات الناجحة تحتاج إلى خدمة مئات الآلاف وربما ملايين المستخدمين في نفس الوقت، مع الحفاظ على الأداء، الأمان، والتوفر العالي. هنا يأتي دور التوسع الأفقي (Horizontal Scaling) وباقي مفاهيم هندسة البرمجيات الخاصة ببناء الأنظمة الكبيرة (Large-Scale Systems).
في هذا المقال سنقدم Horizontal Scaling Explained بشكل مبسط ومنظم، ونتعرف على الفرق بين التوسع الأفقي والتوسع العمودي، ومتى تستخدم كل واحد منهما، وكيف تبني بنية تحتية (Architecture) قادرة على التعامل مع النمو المستمر في عدد المستخدمين.
عندما تبدأ ببناء تطبيق جديد (موقع، API، تطبيق موبايل...) غالباً تضعه على سيرفر واحد: قاعدة بيانات، كود الباك إند، وربما ملفات الصور والفيديو، كلها على نفس الخادم. هذا يكون كافياً في البداية، لكن مع زيادة عدد المستخدمين تظهر مشاكل:
هنا نحتاج إلى التوسع (Scaling)، أي زيادة قدرة النظام على تحمل عدد أكبر من الطلبات (Requests) بدون انهيار أو بطء شديد.
التوسع الأفقي (Horizontal Scaling) يعني إضافة المزيد من الخوادم (Servers) لتوزيع الحمل بينها. بدلاً من سيرفر واحد قوي، يصبح لديك عدة سيرفرات عادية تعمل معاً.
في المقابل، التوسع العمودي (Vertical Scaling) يعني تكبير حجم السيرفر الواحد: زيادة الـ CPU، الذاكرة، السعة التخزينية… إلخ.
في Vertical Scaling، تحاول أن تجعل جهازك الحالي أقوى:
هذا النوع من التوسع سهل نسبياً من ناحية إعداد النظام؛ لأنك لا تغيّر في بنية التطبيق بشكل كبير، فقط تغير في إمكانيات الجهاز. لكنه يأتي مع مجموعة قيود:
في Horizontal Scaling، بدل أن تكبّر سيرفر واحد، تقوم بـ:
هذا الأسلوب هو ما تستخدمه معظم الشركات الكبيرة مثل فيسبوك، تويتر، نتفليكس وغيرها؛ لأنه يوفر:
| العنصر | التوسع العمودي (Vertical) | التوسع الأفقي (Horizontal) |
|---|---|---|
| آلية العمل | تكبير حجم السيرفر نفسه | إضافة المزيد من السيرفرات |
| حد التوسع | محدود بمواصفات الجهاز الواحد | نظرياً غير محدود (يمكنك إضافة عدد كبير من الأجهزة) |
| التوفر (Availability) | نقطة فشل واحدة | أكثر تحملاً للأعطال |
| صعوبة التنفيذ | أسهل في البداية | يحتاج تصميم معماري جيد |
| التكلفة على المدى الطويل | قد تصبح مرتفعة جداً | غالباً أكثر كفاءة في الأنظمة الكبيرة |
في مقال سابق عن مقدمة في System Design للمطورين تحدثنا بشكل عام عن طريقة تفكير الشركات الكبيرة عند تصميم الأنظمة. هنا سنركز على كيف يُستخدم التوسع الأفقي كجزء من هذه الصورة.
لتخدم ملايين المستخدمين، تحتاج إلى معمارية (Architecture) تتكون من عدة طبقات (Layers)، وكل طبقة منها قابلة للتوسع الأفقي.
هذه الطبقة تشمل:
هنا لا يوجد توسع تقني مباشرة من طرفك، بل التركيز على أن الـ API يمكنها استقبال عدد كبير من الاتصالات في نفس الوقت.
هذه هي البوابة الأمامية للنظام. الـ Load Balancer يستقبل جميع الطلبات من المستخدمين ثم يوزعها على مجموعة من السيرفرات (Application Servers).
هذه الطبقة هي قلب النظام؛ فيها كود الباك إند الذي يتعامل مع الطلبات، قواعد العمل (Business Logic)، التحقق من الصلاحيات… إلخ.
في التوسع الأفقي، تقوم عادةً بـ:
الـ Stateless Services (الخدمات التي لا تحتفظ بحالة داخل الذاكرة) أسهل بكثير في التوسع الأفقي، لأن أي سيرفر يمكنه معالجة أي طلب دون الاعتماد على ما قبله.
يمكنك الرجوع إلى مقالنا عن تعلم الدوكر: شرح أساسيات التعامل مع الحاويات لفهم كيف يتم تشغيل خدماتك في حاويات قابلة للتوسع بسهولة.
قواعد البيانات هي غالباً أصعب جزء في التوسع الأفقي؛ لأنها بطبيعتها Statefull وتحتوي على بيانات متغيرة باستمرار.
هناك استراتيجيات متعددة للتعامل معها:
باستخدام هذه التقنيات، يمكن للنظام أن يستمر في التوسع مع زيادة عدد المستخدمين وحجم البيانات في نفس الوقت.
الكاش من أهم العناصر في أي نظام كبير؛ لأنه يقلل الضغط على قواعد البيانات ويُحسن زمن الاستجابة.
الصور، الفيديوهات، ملفات الـ CSS/JS… إلخ، لا يفضل أن تُخزن على نفس سيرفر التطبيق.
رغم مميزاته، التوسع الأفقي ليس سحرياً، هناك تحديات يجب فهمها:
عندما يكون لديك أكثر من سيرفر تطبيق، لا يمكنك الاعتماد على تخزين جلسات المستخدم (Sessions) في ذاكرة سيرفر واحد؛ لأن الطلبات قد تُرسل إلى سيرفر آخر.
الحلول الشائعة:
في أنظمة موزعة، الوصول إلى Strong Consistency دائماً يكون صعباً، خصوصاً مع الـ Sharding والـ Replication. غالباً تضطر للقبول بـ Eventual Consistency في بعض الأجزاء.
هذا يعني أن:
كلما زاد عدد السيرفرات والخدمات، يصبح تتبع الأخطاء أصعب. تحتاج إلى:
مثل هذه الـ Dashboards يمكن أن تبنيها بأدوات مثل Grafana أو حتى باستخدام Python كما شرحنا في كيف تبني Dashboard تفاعلية باستخدام Python وPlotly Dash.
إذا كنت تبني نظاماً جديداً وتريد أن يكون قابلاً للتوسع مستقبلاً، هناك مبادئ مهمة في التصميم:
كلما قلّت البيانات المخزنة داخل ذاكرة السيرفر نفسه واعتمدت أكثر على قواعد بيانات وكاش خارجي، أصبح من السهل إضافة وإزالة السيرفرات بدون قلق على الحالة (State).
تجنب كتابة نظام واحد ضخم (Monolith) معتمد بشدة على نفسه؛ لأن تفكيكه لاحقاً صعب. حتى لو بدأت بـ Monolith (وهذا مقبول جداً في البداية)، حاول:
الـ APIs هي العقد (Contracts) بين الخدمات، وعندما تكون مصممة جيداً يمكن تغيير طريقة التنفيذ الداخلية دون أن تتأثر باقي الأجزاء.
ضع الكاش في أكثر من طبقة:
لكن انتبه لـ Cache Invalidation؛ لأنها من أصعب المشاكل في الأنظمة الكبيرة.
لا يوجد جواب واحد يناسب الجميع، لكن يمكن وضع بعض الإرشادات:
في الواقع، كثير من الأنظمة تمر بمراحل:
بناء نظام يخدم ملايين المستخدمين ليس خطوة واحدة، بل رحلة تبدأ من:
فهم Horizontal Scaling Explained
ابدأ من اليوم في كتابة كود وتصميم بنية تحتية تفكر في التوسع منذ البداية، حتى لو كان مشروعك صغيراً؛ لأن النمو المفاجئ قد يأتي في أي وقت، والنظام الجاهز للتوسع هو الذي سيصمد.
شرح التوسع الأفقي مقابل التوسع العمودي وكيف تبني بنية قادرة على خدمة ملايين المستخدمين.
مساحة اعلانية