أسس التوسّع

من خادمٍ واحد إلى ملايين المستخدمين

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

الفخّ

الجهاز الواحد له حدود صارمة: CPU محدود، وذاكرة محدودة، وبطاقة شبكة واحدة. والأسوأ أنه نقطة فشل وحيدة — إن تعطل، تعطّل منتجك كله معه. التوسّع هو فن إزالة هذه الحدود، عنق زجاجة واحداً في كل مرة.

الخطوات، بالترتيب
  1. افصل قاعدة البيانات على جهاز مستقل. هكذا يتوقف خادم التطبيق وقاعدة البيانات عن التزاحم على CPU والذاكرة — ويمكن ضبط كل منهما لعمله الخاص.
  2. وسّع عمودياً أولاً: اشترِ جهازاً أكبر. لا تغيير في الكود، وراحة فورية. لكن السقف حقيقي — يوجد دائماً «أكبر جهاز ممكن»، وهو دائماً غالٍ.
  3. وسّع أفقياً: أضف خوادم web جديدة خلف load balancer. الموزّع يوزّع الطلبات على المجموعة، ويمكن لأي خادم أن يتعطل دون أن يسقط الموقع كله.
  4. كرّر قاعدة البيانات: قائد (leader) واحد يستقبل الكتابة، وأتباع (followers) يستقبلون القراءة. معظم التطبيقات تقرأ أكثر بكثير مما تكتب، لذا فإن النسخ القرائية تضاعف قدرتك حيث يكون الألم.
  5. أضف cache. الاستعلامات المكلفة والبيانات الساخنة تُقدَّم من الذاكرة في أجزاء من المللي ثانية، وقاعدة البيانات تتنفس أخيراً.
  6. انقل الملفات الثابتة إلى CDN. الصور والفيديوهات والملفات تُقدَّم من خوادم قريبة من المستخدمين بدل أن تعبر الكوكب من مركز بياناتك.
  7. اجعل طبقة web عديمة الحالة (stateless) — انقل الجلسات من ذاكرة الخادم إلى مخزن مشترك. الآن أي خادم يستطيع معالجة أي طلب، والتوسع صار مجرد إضافة أجهزة.
  8. قسّم قاعدة البيانات (sharding). عندما تعجز قاعدة واحدة عن استيعاب البيانات أو الكتابات، وزّعها بمفتاح تقسيم على عدة قواعد. هذا الملاذ الأخير، وليس الأول.
جرّب بنفسك
أرقام صادقة لكل درجة

ضع تقديرات تقريبية على السلّم. خادم web واحد مضبوط يخدم آلافاً إلى عشرات آلاف الطلبات في الثانية — لنقل 10K طلب/ثانية لنقطة API بسيطة تعيد JSON. قاعدة بيانات علائقية واحدة مجهزة جيداً تتحمل بضعة آلاف استعلام في الثانية قبل أن يقاوم القرص والأقفال — لنقل 3–5K. أما الـcache في الذاكرة فينفذ أكثر من 100K عملية في الثانية على عقدة واحدة، لأن الذاكرة بلا seek time وبلا write-ahead log. إذن عند 2K طلب/ثانية، خادم واحد وقاعدة واحدة كافيان. وعند 20K طلب/ثانية تحتاج ثلاثة خوادم web خلف موزّع، وقاعدة البيانات تلهث، وcache يمتص 90% من القراءات يحوّل عاصفة 20K استعلاماً إلى 2K تستطيع القاعدة حملها فعلاً.

عديم الحالة يعني عديم الحالة — فخ الـsticky sessions

الدرجة السابعة هي حيث تغشّ الفرق. الحل الكسول هو sticky sessions: تثبيت كل مستخدم على خادم واحد عند الـload balancer. يعمل حتى يتعطل خادم مثبَّت عليه مستخدمون — فيفقد كل من التصق به جلسته دفعة واحدة، ويصبح الـfailover خروجاً جماعياً من الحسابات. والأسوأ أن التوزيع يتعطل: بضعة مستخدمين ثقيلين يلتصقون بجهاز واحد فيذوب بينما جيرانه فارغون. الحل الحقيقي هو إخراج حالة الجلسة من الخوادم كلياً، إلى cache مشترك أو مخزن جلسات مركزي يستطيع أي خادم web قراءته. الآن موت خادم لا يعني شيئاً — الموزّع يوجّه الطلبات إلى الناجين فحسب.

المبدأ

كل خطوة توسّع هي نفس الحلقة: اكتشف عنق الزجاجة ← أضف طبقة ← اقبل التعقيد الجديد الذي تجلبه تلك الطبقة. التوسّع سُلّم وليس مفتاح كهرباء — تصعد درجة واحدة عندما تبدأ الدرجة الحالية بالتشقق، ولا تصعد خمس درجات دفعة واحدة أبداً.

مزلق

الخطأ الكلاسيكي هو التوزيع قبل أن تحتاجه. كل طبقة تضيفها — load balancer أو نسخ مكررة أو cache أو shards — هي تعقيد تدفع ثمنه كل يوم: في الأخطاء، وفي النشر، وفي ليالي المناوبة. خادم واحد ممل يتحمل حملك أفضل من نظام موزّع لا تحتاجه.

الحدّ الصادق

طبقة واحدة غائبة عن هذا السلّم: الـmessage queue. تدخل عندما لا يجب أن يحدث العمل داخل الطلب نفسه — إرسال بريد، تصغير صور، خصم بطاقات — أو عندما تسحَق ذروةٌ قاعدةَ بياناتك: تهبط الكتابات في الطابور فوراً، ويفرّغه عمال (workers) بإيقاع تنجو منه القاعدة. هذا نوع مختلف من التوسّع: لا خدمة طلبات أكثر، بل فصلُ وقت تنفيذ العمل عن وقت طلبه. أمسك هذه الفكرة — ستنال درساً خاصاً بها.

تحقّق سريع

خوادم الـweb لديك تحتفظ بجلسات المستخدمين في الذاكرة، وأضفت خادماً ثانياً خلف load balancer — ما الذي سينكسر؟ (الموزّع سيرسل طلب المستخدم التالي إلى الخادم الآخر الذي لم يرَ جلسته قط: فجأة يجد المستخدم نفسه خارج حسابه. الحل هو طبقة stateless — تنتقل الجلسات إلى مخزن مشترك مثل cache.)

الخلاصة

لا أحد يصمم لمليون مستخدم من اليوم الأول. يبدأون بخادم واحد، ويراقبونه وهو يتشقق، ثم يصعدون السلّم: افصل، وسّع عمودياً، وسّع أفقياً، كرّر، cache، CDN، stateless، sharding — عنق زجاجة واحد في كل مرة.

📌 افعل هذا الاثنين

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

أسس التوسّع