البداية · فصل ١

من يوزر واحد لملايين اليوزرز

Scale from zero · load balancer · cache · CDN · sharding
🎯 الهدف: تطلع من الفصل وانت معاك علبة أدوات تقدر ترسم بيها أي سيستم في الإنترفيو.

الفكرة الكبيرة في كلمتين

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

Load BalancerReplicationCacheCDNStatelessData CentersMessage QueueShardingMonitoring

البداية: سيرفر واحد شايل كل حاجة

في الأول، الـ web app والداتابيز والكاش كلهم قاعدين على ماكينة واحدة. زي محل كشري صغير: نفس الراجل بياخد الأوردر ويطبخ ويحاسب.

  1. اليوزر بيكتب الدومين، والـ DNS (غالبًا خدمة خارجية) بيترجمه لـ IP — زي دليل التليفونات.
  2. البراوزر أو الموبايل بياخد الـ IP ويبعت HTTP request للسيرفر على طول.
  3. السيرفر بيرد بـ HTML لو ويب، أو JSON لو API للموبايل.

أول فصل: الداتابيز في سيرفر لوحدها

أول ما اليوزرز يزيدوا، بنفصل سيرفر الويب عن سيرفر الداتا. المزية إن كل واحد فيهم يكبر لوحده.

النوعأمثلةإمتى تختاره؟
Relational (SQL)PostgreSQL, MySQL, Oracleالاختيار الافتراضي: جداول وعلاقات و JOIN، ومستقر من عشرات السنين
Non-Relational (NoSQL)Cassandra, DynamoDB, MongoDB, Neo4jlatency قليلة جدًا، أو الداتا مش متهيكلة، أو كمية مهولة، أو بس بتعمل serialize لـ JSON
Key-ValueGraphColumnDocument

تكبير لفوق ولا تكبير بالعرض؟

⬆ Vertical — Scale Up

تزوّد CPU و RAM لنفس الماكينة. زي ما تكبّر المطبخ بدل ما تفتح فرع.

  • بسيط جدًا لما الترافيك قليل.
  • ليه سقف: مفيش ماكينة بتكبر للنهاية.
  • لو وقعت، كله وقع.
↔ Horizontal — Scale Out

تضيف سيرفرات أكتر جنب بعض. زي ما تفتح فروع.

  • مفيش سقف تقريبًا.
  • لو سيرفر وقع، الباقي شغال.
  • ده اللي بيتعمل في الـ large-scale systems.

الـ Load Balancer: عسكري المرور

بيقف قدام السيرفرات ويوزّع الترافيك عليهم. اليوزر بيكلم IP عام واحد بتاع الـ LB، والسيرفرات نفسها بتتكلم على private IPs مش ظاهرة للإنترنت.

سيرفر وقع؟ الـ LB يحوّل الترافيك على الباقيين وخلاص. الترافيك زاد؟ ضيف سيرفرات للـ pool والـ LB يبتدي يبعتلهم تلقائي.

نسخ الداتابيز

نسخة رئيسية (Primary) بتستقبل الكتابة بس، ونسخ (Replicas) بتاخد نسخة من الداتا وبتخدم القراءة. أغلب التطبيقات القراءة فيها أكتر بكتير من الكتابة، فعدد الـ replicas بيبقى أكبر.

المكسبليه؟
Performanceالقراءات بتتوزع على كذا نسخة بالتوازي
Reliabilityلو سيرفر اتدمر، الداتا موجودة في أماكن تانية
Availabilityنسخة وقعت؟ الشغل يكمل من نسخة تانية

الكاش: الدرج اللي جنبك

بدل ما كل مرة تنزل المخزن (الداتابيز) تجيب نفس الحاجة، تحطها في درج جنبك في الميموري. الكاش تخزين مؤقت وسريع للحاجات التقيلة أو اللي بتتطلب كتير.

أدوات شائعة: Memcached و Redis، بـ API بسيط زي set(key, value, ttl) و get(key).

النقطةالمعنى بالمصري
إمتى أستخدمهالداتا بتتقرى كتير وبتتغير قليل. ومتخزنش فيه حاجة مهمة لوحدها — الميموري بتتمسح لو السيرفر عمل restart
Expirationلازم مدة صلاحية. قصيرة قوي = هترجع للداتابيز كتير. طويلة قوي = داتا بايتة
Consistencyالكتابة في الداتابيز والكاش مش في transaction واحدة، فممكن يحصل اختلاف
SPOFكاش سيرفر واحد = نقطة فشل واحدة. خلّي عندك أكتر من سيرفر
Evictionالكاش اتملى؟ ترمي حاجة. الأشهر LRU (الأقدم استخدامًا)، وفيه LFU و FIFO

الـ CDN: فروع قريبة من اليوزر

شبكة سيرفرات منتشرة في العالم بتشيل المحتوى الثابت: صور، فيديو، CSS، JS. اليوزر اللي في القاهرة ياخد الصورة من أقرب سيرفر ليه بدل ما تيجي من أمريكا.

سيرفر من غير ذاكرة

عشان نكبّر الـ web tier بالعرض بحرية، لازم نشيل الـ state (زي الـ session بتاعة اليوزر) من جوه السيرفر.

😖 Stateful

بيانات اليوزر A محفوظة في Server 1 بس. يبقى لازم كل ريكوست بتاعه يروح لـ Server 1 (sticky sessions). إضافة أو شيل سيرفر بقت وجع دماغ، والـ failover صعب.

😎 Stateless

الـ session متخزنة في مكان مشترك (Redis أو NoSQL أو RDBMS). أي سيرفر يقدر يخدم أي ريكوست. تقدر تعمل auto-scaling براحتك.

أكتر من Data Center

لما يبقى عندك يوزرز في كذا قارة، بتوزع السيستم على كذا داتا سنتر. الـ GeoDNS بيوجّه كل يوزر لأقرب داتا سنتر ليه. ولو داتا سنتر وقع كله، الترافيك يروح على اللي شغال.

صندوق البوستة: Message Queue

كومبوننت بيخزن رسايل وبيسمح بشغل asynchronous. الـ Producer بيرمي رسالة في الطابور، والـ Consumer بيسحبها ويشتغل عليها لما يفضى.

المزية الكبيرة decoupling: الـ producer يقدر يبعت حتى لو الـ consumer مش متاح. ولو الطابور كبر، زوّد workers. لو فاضي، قلّلهم.

اللوجز والمقاييس والأوتوميشن

لما السيستم يكبر، لازم تشوف جواه وتشغّله من غير ما تعمل كل حاجة بإيدك.

الأداةالفايدة
Loggingتتابع الإيرورز. الأحسن تجمعها في مكان مركزي بدل ما تدخل على كل سيرفر
MetricsHost: CPU وميموري و Disk I/O. Aggregated: أداء الداتابيز كطبقة. Business: DAU و retention و revenue
AutomationCI بيتأكد إن كل commit سليم، وأوتوميشن للـ build والتيست والـ deploy

تكبير الداتابيز: Sharding

نفس فكرة الـ web tier. Vertical (ماكينة أقوى) ليه سقف وتكلفته عالية وبيبقى SPOF. Horizontal = sharding: تقسم الداتا على كذا داتابيز.

كل shard ليه نفس الـ schema بس فيه جزء مختلف من الداتا. بتختار sharding key (زي user_id) ودالة زي user_id % 4 تحدد اليوزر ده في أنهي shard. أهم قاعدة: اختار key يوزّع الداتا بالتساوي.

المشكلةالشرح والحل
Reshardingshard اتملى أو التوزيع مش متساوي، فلازم تغيّر الدالة وتنقل داتا. الحل الشهير: Consistent Hashing (الفصل الجاي)
Celebrity / Hotspotshard عليه يوزرز مشاهير فبيتضرب ضرب. الحل: تدي كل مشهور shard لوحده، أو تقسم أكتر
Joinالـ JOIN بين shards صعب. الحل الشائع: de-normalize وتكرر الداتا عشان الكويري يتعمل على جدول واحد

ممكن كمان تنقل حاجات من الداتابيز لـ NoSQL عشان تخفف الحمل، خصوصًا الداتا اللي مش محتاجة علاقات.

السيستم في شكله الأخير

وبعد الويب: كاش + داتابيز متقسمة ونسخها، وطابور و workers، ولوجز ومقاييس و CI، على أكتر من داتا سنتر.

Checklist الملايين

🧠 اختبر نفسك
١) ليه الـ vertical scaling مش كفاية للسيستمز الكبيرة؟
ليه سقف في الهاردوير، ومفيش redundancy: لو الماكينة وقعت، كله وقع.
٢) إيه اللي بيحصل لو الـ primary DB وقع؟
replica تترقى لـ primary، مع recovery للداتا اللي لسه موصلتش للنسخة.
٣) امتى الكاش يبقى فكرة وحشة؟
لما الداتا بتتغير كتير، أو لو هتعتمد عليه كمخزن دائم.
٤) ليه لازم الـ web tier يبقى stateless؟
عشان أي سيرفر يخدم أي ريكوست، فتعرف تعمل auto-scaling من غير sticky sessions.
٥) إيه مشكلة الـ celebrity في الـ sharding؟
shard واحد عليه ضغط أكبر بكتير من الباقي — hotspot.