أساسيات تصميم الأنظمة

قابلية التوسع والموثوقية وقابلية الصيانة

18 دقيقة الدرس 6 من 10

قابلية التوسع والموثوقية وقابلية الصيانة

يُقاس كل نظام واسع النطاق في نهاية المطاف بثلاث صفات: هل يستطيع النمو دون أن ينهار؟ هل يستمر في العمل حين تسوء الأمور؟ وهل يستطيع المهندسون تعديله دون خوف؟ هذه الركائز الثلاث — قابلية التوسع، والموثوقية، وقابلية الصيانة — هي المنظار الذي يُقيّم من خلاله المهندسون المتمرسون كل قرار معماري.

١. قابلية التوسع — التعامل مع النمو

قابلية التوسع هي قدرة النظام على استيعاب حجم عمل متزايد عبر إضافة موارد. وهي تجيب على السؤال: "إذا تضاعفت الأحمال، ماذا يحدث؟"

التوسع الرأسي مقابل التوسع الأفقي

  • التوسع الرأسي (ترقية الجهاز): تزويد جهاز واحد بمزيد من المعالج أو الذاكرة أو الأقراص الأسرع. البداية بسيطة — لا حاجة لتغيير الكود — لكنه يصطدم بسقف صلب. أضخم نسخة من EC2 في AWS تحتوي على 192 وحدة معالجة و1.5 تيرابايت ذاكرة؛ ما بعد ذلك لا مجال للترقية.
  • التوسع الأفقي (إضافة أجهزة): إضافة مزيد من الأجهزة وتوزيع الحمل عليها. هكذا تعمل عمالقة الإنترنت؛ نتفليكس مثلاً تعمل على عشرات الآلاف من نسخ الحوسبة السحابية. المقايضة هي التعقيد الإضافي: يجب التعامل مع توزيع البيانات والاتصالات الشبكية والاتساق.
Vertical vs Horizontal Scaling Vertical Scaling (Scale Up) Server 4 CPU / 8 GB upgrade Bigger Server 64 CPU / 256 GB hits a ceiling Horizontal Scaling (Scale Out) Load Balancer Server 1 Server 2 Server 3 + add more nodes as load grows theoretically unbounded
التوسع الرأسي يُرقّي جهازاً واحداً؛ أما التوسع الأفقي فيوزّع الحمل على أجهزة متعددة.

قياس قابلية التوسع: معايير الحمل

قبل أي تحسين، يجب تحديد ما يعنيه الحمل لنظامك. تشمل معايير الحمل الشائعة:

  • عدد الطلبات في الثانية على الخادم
  • نسبة القراءة إلى الكتابة في قاعدة البيانات (خلاصة تويتر ~100:1 قراءة)
  • عدد المستخدمين النشطين بالتزامن في نظام الدردشة
  • نسبة الإصابة في الذاكرة المؤقتة (Cache Hit Rate)

اختر الأرقام الأكثر أهمية لنظامك، ثم اسأل: إذا تضاعف هذا الرقم عشر مرات، كيف يستجيب النظام؟

نصيحة تصميمية: الحالة المحلية (State) عدوّة التوسع الأفقي. إذا خزّن كل خادم بيانات الجلسة محلياً، لن تتمكن من توجيه المستخدم إلى أي خادم بحرية. ادفع الحالة إلى طبقة مشتركة (Redis أو قاعدة بيانات) بحيث يتمكن أي خادم من معالجة أي طلب — وهذا ما يُعرف بـالمعمارية عديمة الحالة.

٢. الموثوقية — الاستمرار في العمل الصحيح

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

فئات الأعطال الثلاث

  • أعطال الأجهزة: تعطل الأقراص الصلبة، أخطاء الذاكرة، فشل بطاقات الشبكة. في المقياس الكبير هذه أمور روتينية — مجموعة من 10,000 خادم ترى عدة أعطال أقراص كل يوم. الحل هو التكرار: مصفوفات RAID، إمدادات طاقة مزدوجة، خوادم احتياطية.
  • أعطال البرمجيات: العمليات المنفلتة، الأخطاء التي تُثيرها مدخلات محددة، الفشل المتسلسل حيث يجرّ الخدمة A الخدمة B التي تجرّ الخدمة C. هذه أصعب في الوقاية لأنها غالباً منهجية — الافتراض الخاطئ ذاته موجود في كل نسخة.
  • الأخطاء البشرية: إعدادات تكوين خاطئة، ترحيلات قاعدة بيانات خاطئة، حذف عرضي. تُظهر الدراسات باستمرار أن الأخطاء البشرية هي السبب الأكبر للانقطاعات الفعلية.

تحمل الأعطال مقابل منعها

لا يمكنك منع جميع الأعطال، لذا تُصمَّم الأنظمة الموثوقة لـتحمّلها. التقنيات الرئيسية:

  • التكرار: تضعيف المكونات الحرجة (قاعدة بيانات رئيسية + نسخة، نشر متعدد مناطق التوفر). إذا فشل أحدها، يتولى الآخر المهمة.
  • التدهور الرشيق: عندما تتعطل خدمة التوصيات، اعرض قسماً فارغاً — لا تُعطّل الصفحة بأكملها.
  • الحواجز (Bulkheads): عزل الأنظمة الفرعية حتى لا ينتشر الفشل. مستوحى من الحجرات المانعة للتسرب في السفن.
  • هندسة الفوضى: إدخال أعطال متعمدة في الإنتاج (Chaos Monkey من نتفليكس) لإثبات أن النظام يتعامل معها قبل أن يفعل حادث حقيقي.
خطأ شائع: نظام بخمسة تسعات من وقت تشغيل الأجهزة قد يظل غير موثوق إذا كانت عمليات النشر يدوية وعرضة للأخطاء. الموثوقية تتطلب انضباطاً في العمليات بقدر ما تتطلب تكراراً تقنياً.

٣. قابلية الصيانة — العيش مع النظام

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

قابلية التشغيل (Operability)

اجعل من السهل على فرق العمليات الحفاظ على تشغيل النظام بسلاسة. الأنظمة الجيدة تكشف المقاييس والسجلات، وتوفر لوحات تحكم، وتدعم إعادة التشغيل الآمنة، وتُسهّل فهم الحالة الصحية الحالية. نظام يبدو "صندوقاً أسود" مكلف التشغيل.

البساطة (Simplicity)

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

قابلية التطوير (Evolvability)

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

The Three Pillars of a Reliable System Three Pillars of a Production-Ready System Scalability Handle growth • Vertical scaling • Horizontal scaling • Stateless design • Load balancing • Sharding / partitioning • Caching layers Goal: 10x load = same latency Reliability Work correctly • Redundancy • Graceful degradation • Bulkheads • Circuit breakers • Chaos engineering • Automated recovery Goal: fail safely, recover fast Maintainability Change safely • Operability • Observability • Simplicity • Good abstractions • Evolvability • API versioning Goal: fearless change
الركائز الثلاث التي يجب أن يوازن بينها كل نظام إنتاجي: النمو، والصحة، والقابلية للتغيير.

كيف تتفاعل الركائز الثلاث

هذه الصفات ليست مستقلة — بل تتجاذب في اتجاهات مثيرة للاهتمام:

  • قابلية التوسع مقابل الموثوقية: توزيع البيانات على عقد كثيرة (يتوسع جيداً) يعني أنك يجب أن تتعامل الآن مع حالات الفشل الجزئي والاتساق التدريجي. قاعدة بيانات ذات سيد واحد أبسط في الاستدلال عليها بموثوقية، لكنها تصطدم بقيود التوسع.
  • قابلية التوسع مقابل قابلية الصيانة: معمارية الخدمات المصغرة تتيح توسيع الخدمات الفردية بشكل مستقل، لكن نظاماً من 200 خدمة أصعب بكثير في التشغيل والاستدلال مقارنة بالنظام المتكامل المنظم جيداً.
  • الموثوقية مقابل قابلية الصيانة: إضافة التكرار — مراكز بيانات متعددة، منطق تحويل احتياطي معقد — تزيد من تعقيد التشغيل. الأنظمة ذات أربعة تسعات من وقت التشغيل مكلفة الصيانة.
الفهم الجوهري: لا توجد موازنة صحيحة بشكل مطلق. الشركة الناشئة التي تعالج 1,000 طلب يومياً يجب أن تُحسّن قابلية الصيانة (التحرك بسرعة). معالج المدفوعات الذي يتعامل مع مليارات المعاملات يجب أن يُحسّن الموثوقية. الشبكة الاجتماعية التي تنمو 50% شهرياً يجب أن تُحسّن قابلية التوسع. السياق هو الذي يحدد الأولوية.

أهداف عملية

تمنح أهداف مستوى الخدمة الواقعية هذه الركائز أرقاماً ملموسة:

  • قابلية التوسع: "يجب أن يتعامل النظام مع 50,000 طلب/ثانية بكمون p99 أقل من 200 مللي ثانية، وأن يتوسع إلى 200,000 طلب/ثانية دون تغييرات في الكود — فقط بإضافة عقد."
  • الموثوقية: "يجب أن تحقق الخدمة 99.9% من وقت التشغيل الشهري (43 دقيقة من التوقف مسموح بها). لا يجب أن يتسبب فشل أي عقدة واحدة في أخطاء مرئية للمستخدم."
  • قابلية الصيانة: "متوسط الوقت لنشر ميزة أقل من ساعة واحدة. أي مهندس مناوب يستطيع تشخيص الحوادث النموذجية والتعافي منها باستخدام لوحات التحكم وحدها دون قراءة الكود المصدري."

الحفاظ على وضوح هذه الأهداف — مكتوبة في وثيقة التصميم، ومتتبعة في لوحات التحكم — هو ما يُميّز النظام الذي يدوم سنوات عن ذلك الذي يصبح غير قابل للصيانة بمجرد مغادرة أصحابه الأصليين.