Ghaymah intern
هذا الالتزام موجود في:
154
q4-scalability/architecture-diagram.svg
Normal file
154
q4-scalability/architecture-diagram.svg
Normal file
@@ -0,0 +1,154 @@
|
||||
<svg viewBox="0 0 1100 1150" xmlns="http://www.w3.org/2000/svg" font-family="Segoe UI, Tahoma, Arial, sans-serif">
|
||||
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||
<path d="M0,0 L0,6 L9,3 z" fill="#4f8cff"/>
|
||||
</marker>
|
||||
<marker id="arrowGray" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||
<path d="M0,0 L0,6 L9,3 z" fill="#5b6579"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<rect x="0" y="0" width="1100" height="1150" fill="#0b0f18"/>
|
||||
|
||||
<!-- ============ TITLE ============ -->
|
||||
<text x="550" y="40" text-anchor="middle" fill="#f2f5fb" font-size="24" font-weight="700">
|
||||
معمارية تطبيق يستقبل 15,000 request/second على غيمة
|
||||
</text>
|
||||
<text x="550" y="62" text-anchor="middle" fill="#8b96ab" font-size="13">
|
||||
High Availability · Auto-scaling · Stateless Compute + Persistent Storage
|
||||
</text>
|
||||
|
||||
<!-- ============ SECTION 1: CLIENT / EDGE ============ -->
|
||||
<rect x="40" y="90" width="1020" height="120" rx="14" fill="#111827" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="65" y="115" fill="#5b6579" font-size="12" font-weight="700" letter-spacing="1">01 · طبقة العميل والحافة</text>
|
||||
|
||||
<rect x="440" y="130" width="220" height="55" rx="10" fill="#171f30" stroke="#4f8cff" stroke-width="2"/>
|
||||
<text x="550" y="153" text-anchor="middle" fill="#e7ecf5" font-size="14" font-weight="600">المستخدمون</text>
|
||||
<text x="550" y="171" text-anchor="middle" fill="#4f8cff" font-size="13" font-weight="700">15,000 request/second</text>
|
||||
|
||||
<line x1="440" y1="157" x2="290" y2="157" stroke="#5b6579" stroke-width="1.5" marker-end="url(#arrowGray)"/>
|
||||
<rect x="90" y="130" width="200" height="55" rx="10" fill="#171f30" stroke="#5b6579" stroke-width="1.5"/>
|
||||
<text x="190" y="153" text-anchor="middle" fill="#c7cedb" font-size="13" font-weight="600">CDN</text>
|
||||
<text x="190" y="171" text-anchor="middle" fill="#8b96ab" font-size="10">ملفات ثابتة (Static assets)</text>
|
||||
|
||||
<line x1="660" y1="157" x2="810" y2="157" stroke="#5b6579" stroke-width="1.5" marker-end="url(#arrowGray)"/>
|
||||
<rect x="810" y="130" width="200" height="55" rx="10" fill="#171f30" stroke="#5b6579" stroke-width="1.5"/>
|
||||
<text x="910" y="153" text-anchor="middle" fill="#c7cedb" font-size="13" font-weight="600">DNS</text>
|
||||
<text x="910" y="171" text-anchor="middle" fill="#8b96ab" font-size="10">توجيه الدومين للـ Load Balancer</text>
|
||||
|
||||
<line x1="550" y1="185" x2="550" y2="240" stroke="#4f8cff" stroke-width="2.5" marker-end="url(#arrow)"/>
|
||||
<text x="575" y="215" fill="#4f8cff" font-size="11">كل الترافيك (15,000 req/s)</text>
|
||||
|
||||
<!-- ============ SECTION 2: LOAD BALANCER ============ -->
|
||||
<rect x="40" y="240" width="1020" height="110" rx="14" fill="#111827" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="65" y="265" fill="#5b6579" font-size="12" font-weight="700" letter-spacing="1">02 · موازنة الأحمال</text>
|
||||
|
||||
<rect x="330" y="280" width="440" height="55" rx="10" fill="#132b21" stroke="#2ecc71" stroke-width="2.5"/>
|
||||
<text x="550" y="303" text-anchor="middle" fill="#2ecc71" font-size="15" font-weight="700">Ghaymah Load Balancer</text>
|
||||
<text x="550" y="322" text-anchor="middle" fill="#9fd9b8" font-size="11">Round-robin + Health Check على /health كل 30 ثانية</text>
|
||||
|
||||
<line x1="550" y1="335" x2="550" y2="380" stroke="#4f8cff" stroke-width="2.5" marker-end="url(#arrow)"/>
|
||||
<text x="575" y="362" fill="#4f8cff" font-size="11">توزيع تلقائي على 39 حاوية</text>
|
||||
|
||||
<!-- ============ SECTION 3: APPLICATION TIER ============ -->
|
||||
<rect x="40" y="380" width="1020" height="330" rx="14" fill="#111827" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="65" y="405" fill="#5b6579" font-size="12" font-weight="700" letter-spacing="1">03 · طبقة التطبيق (Auto-scaling Group)</text>
|
||||
|
||||
<rect x="65" y="418" width="970" height="34" rx="8" fill="#0f1420" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="90" y="440" fill="#c7cedb" font-size="12">39 حاوية Stateless</text>
|
||||
<text x="380" y="440" fill="#8b96ab" font-size="12">سعة الحاوية: 500 req/s</text>
|
||||
<text x="620" y="440" fill="#8b96ab" font-size="12">هامش أمان: 30%</text>
|
||||
<text x="830" y="440" fill="#f5a623" font-size="12" font-weight="700">≈ 385 req/s فعليًا لكل حاوية</text>
|
||||
|
||||
<!-- Container grid: 13 columns x 3 rows = 39 -->
|
||||
<!-- Az label boxes -->
|
||||
<rect x="65" y="465" width="310" height="220" rx="10" fill="#0f1420" stroke="#3a4560" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<text x="220" y="485" text-anchor="middle" fill="#8b96ab" font-size="11">Availability Zone A</text>
|
||||
|
||||
<rect x="395" y="465" width="310" height="220" rx="10" fill="#0f1420" stroke="#3a4560" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<text x="550" y="485" text-anchor="middle" fill="#8b96ab" font-size="11">Availability Zone B</text>
|
||||
|
||||
<rect x="725" y="465" width="310" height="220" rx="10" fill="#0f1420" stroke="#3a4560" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
<text x="880" y="485" text-anchor="middle" fill="#8b96ab" font-size="11">Availability Zone C</text>
|
||||
|
||||
<!-- Zone A containers: 13 -->
|
||||
<g fill="#1c2942" stroke="#4f8cff" stroke-width="1">
|
||||
<rect x="90" y="500" width="52" height="36" rx="6"/><rect x="152" y="500" width="52" height="36" rx="6"/><rect x="214" y="500" width="52" height="36" rx="6"/><rect x="276" y="500" width="52" height="36" rx="6"/>
|
||||
<rect x="90" y="546" width="52" height="36" rx="6"/><rect x="152" y="546" width="52" height="36" rx="6"/><rect x="214" y="546" width="52" height="36" rx="6"/><rect x="276" y="546" width="52" height="36" rx="6"/>
|
||||
<rect x="90" y="592" width="52" height="36" rx="6"/><rect x="152" y="592" width="52" height="36" rx="6"/><rect x="214" y="592" width="52" height="36" rx="6"/><rect x="276" y="592" width="52" height="36" rx="6"/>
|
||||
<rect x="90" y="638" width="52" height="36" rx="6"/>
|
||||
</g>
|
||||
<text x="116" y="522" text-anchor="middle" fill="#8fb4ff" font-size="10">C1</text>
|
||||
<text x="116" y="656" text-anchor="middle" fill="#8fb4ff" font-size="10">C13</text>
|
||||
<text x="220" y="670" text-anchor="middle" fill="#5b6579" font-size="10">13 حاوية</text>
|
||||
|
||||
<!-- Zone B containers: 13 -->
|
||||
<g fill="#1c2942" stroke="#4f8cff" stroke-width="1">
|
||||
<rect x="420" y="500" width="52" height="36" rx="6"/><rect x="482" y="500" width="52" height="36" rx="6"/><rect x="544" y="500" width="52" height="36" rx="6"/><rect x="606" y="500" width="52" height="36" rx="6"/>
|
||||
<rect x="420" y="546" width="52" height="36" rx="6"/><rect x="482" y="546" width="52" height="36" rx="6"/><rect x="544" y="546" width="52" height="36" rx="6"/><rect x="606" y="546" width="52" height="36" rx="6"/>
|
||||
<rect x="420" y="592" width="52" height="36" rx="6"/><rect x="482" y="592" width="52" height="36" rx="6"/><rect x="544" y="592" width="52" height="36" rx="6"/><rect x="606" y="592" width="52" height="36" rx="6"/>
|
||||
<rect x="420" y="638" width="52" height="36" rx="6"/>
|
||||
</g>
|
||||
<text x="446" y="522" text-anchor="middle" fill="#8fb4ff" font-size="10">C14</text>
|
||||
<text x="446" y="656" text-anchor="middle" fill="#8fb4ff" font-size="10">C26</text>
|
||||
<text x="550" y="670" text-anchor="middle" fill="#5b6579" font-size="10">13 حاوية</text>
|
||||
|
||||
<!-- Zone C containers: 13 -->
|
||||
<g fill="#1c2942" stroke="#4f8cff" stroke-width="1">
|
||||
<rect x="750" y="500" width="52" height="36" rx="6"/><rect x="812" y="500" width="52" height="36" rx="6"/><rect x="874" y="500" width="52" height="36" rx="6"/><rect x="936" y="500" width="52" height="36" rx="6"/>
|
||||
<rect x="750" y="546" width="52" height="36" rx="6"/><rect x="812" y="546" width="52" height="36" rx="6"/><rect x="874" y="546" width="52" height="36" rx="6"/><rect x="936" y="546" width="52" height="36" rx="6"/>
|
||||
<rect x="750" y="592" width="52" height="36" rx="6"/><rect x="812" y="592" width="52" height="36" rx="6"/><rect x="874" y="592" width="52" height="36" rx="6"/><rect x="936" y="592" width="52" height="36" rx="6"/>
|
||||
<rect x="750" y="638" width="52" height="36" rx="6"/>
|
||||
</g>
|
||||
<text x="776" y="522" text-anchor="middle" fill="#8fb4ff" font-size="10">C27</text>
|
||||
<text x="776" y="656" text-anchor="middle" fill="#8fb4ff" font-size="10">C39</text>
|
||||
<text x="880" y="670" text-anchor="middle" fill="#5b6579" font-size="10">13 حاوية</text>
|
||||
|
||||
<text x="550" y="705" text-anchor="middle" fill="#8b96ab" font-size="11" font-style="italic">
|
||||
توزيع متساوٍ عبر 3 مناطق توفر لضمان استمرار الخدمة حتى لو تعطلت منطقة كاملة
|
||||
</text>
|
||||
|
||||
<line x1="220" y1="710" x2="220" y2="750" stroke="#5b6579" stroke-width="1.5" marker-end="url(#arrowGray)"/>
|
||||
<line x1="550" y1="710" x2="550" y2="750" stroke="#4f8cff" stroke-width="2.5" marker-end="url(#arrow)"/>
|
||||
<line x1="880" y1="710" x2="880" y2="750" stroke="#5b6579" stroke-width="1.5" marker-end="url(#arrowGray)"/>
|
||||
|
||||
<!-- ============ SECTION 4: DATA / CACHING TIER ============ -->
|
||||
<rect x="40" y="750" width="1020" height="130" rx="14" fill="#111827" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="65" y="775" fill="#5b6579" font-size="12" font-weight="700" letter-spacing="1">04 · طبقة الكاش وتجميع الاتصالات</text>
|
||||
|
||||
<rect x="150" y="790" width="330" height="65" rx="10" fill="#221a0c" stroke="#f5a623" stroke-width="2"/>
|
||||
<text x="315" y="815" text-anchor="middle" fill="#f5a623" font-size="14" font-weight="700">Valkey (In-memory Cache)</text>
|
||||
<text x="315" y="834" text-anchor="middle" fill="#d8b98a" font-size="11">تقليل القراءات المتكررة من قاعدة البيانات</text>
|
||||
|
||||
<rect x="620" y="790" width="330" height="65" rx="10" fill="#221a0c" stroke="#f5a623" stroke-width="2"/>
|
||||
<text x="785" y="815" text-anchor="middle" fill="#f5a623" font-size="14" font-weight="700">PgBouncer (Connection Pooler)</text>
|
||||
<text x="785" y="834" text-anchor="middle" fill="#d8b98a" font-size="11">39 حاوية → مجموعة اتصالات محدودة بدل 39 اتصال منفصل</text>
|
||||
|
||||
<line x1="315" y1="855" x2="315" y2="885" stroke="#4f8cff" stroke-width="2" marker-end="url(#arrow)"/>
|
||||
<line x1="785" y1="855" x2="785" y2="885" stroke="#4f8cff" stroke-width="2" marker-end="url(#arrow)"/>
|
||||
<line x1="315" y1="885" x2="785" y2="885" stroke="#5b6579" stroke-width="1" stroke-dasharray="4,3"/>
|
||||
|
||||
<!-- ============ SECTION 5: STATEFUL / STORAGE ============ -->
|
||||
<rect x="40" y="900" width="1020" height="150" rx="14" fill="#111827" stroke="#2a3448" stroke-width="1"/>
|
||||
<text x="65" y="925" fill="#5b6579" font-size="12" font-weight="700" letter-spacing="1">05 · طبقة البيانات الدائمة (Stateful)</text>
|
||||
|
||||
<rect x="330" y="940" width="290" height="90" rx="10" fill="#26120f" stroke="#e74c3c" stroke-width="2.5"/>
|
||||
<text x="475" y="965" text-anchor="middle" fill="#e74c3c" font-size="14" font-weight="700">PostgreSQL</text>
|
||||
<text x="475" y="983" text-anchor="middle" fill="#e6a8a0" font-size="11">Primary + Read Replica</text>
|
||||
<text x="475" y="1001" text-anchor="middle" fill="#8b96ab" font-size="10">الوحيدة صاحبة حالة (Stateful) في المعمارية</text>
|
||||
|
||||
<line x1="620" y1="985" x2="680" y2="985" stroke="#e74c3c" stroke-width="2" marker-end="url(#arrow)"/>
|
||||
<rect x="680" y="940" width="290" height="90" rx="10" fill="#170f24" stroke="#a17ae0" stroke-width="2.5"/>
|
||||
<text x="825" y="965" text-anchor="middle" fill="#c3a3f2" font-size="14" font-weight="700">Ghaymah Block Storage</text>
|
||||
<text x="825" y="983" text-anchor="middle" fill="#a894c9" font-size="11">Persistent Volume مستقل عن الحاوية</text>
|
||||
<text x="825" y="1001" text-anchor="middle" fill="#8b96ab" font-size="10">البيانات باقية حتى لو الحاوية اتستبدلت</text>
|
||||
|
||||
<!-- ============ SECTION 6: MONITORING (side panel) ============ -->
|
||||
<rect x="40" y="1065" width="1020" height="70" rx="14" fill="#0f1e17" stroke="#2ecc71" stroke-width="1.5"/>
|
||||
<text x="65" y="1090" fill="#2ecc71" font-size="12" font-weight="700" letter-spacing="1">06 · المراقبة (تراقب كل الطبقات أعلاه)</text>
|
||||
<text x="380" y="1090" fill="#9fd9b8" font-size="12">Grafana — اتجاه الموارد (CPU/Memory)</text>
|
||||
<text x="700" y="1090" fill="#9fd9b8" font-size="12">Uptime Kuma — فحص /health كل 30 ثانية</text>
|
||||
<text x="65" y="1112" fill="#6fa88a" font-size="10">تنبيهات فورية عند 70%/90% استخدام موارد، أو فشل أي فحص صحة</text>
|
||||
|
||||
</svg>
|
||||
|
بعد العرض: | الارتفاع: | الحجم: 12 KiB |
133
q4-scalability/scalability-report.md
Normal file
133
q4-scalability/scalability-report.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# قابلية التوسع وتوزيع الأحمال — تطبيق يستقبل 15,000 req/s على غيمة
|
||||
|
||||
## 1. Architecture Diagram
|
||||
|
||||

|
||||
|
||||
### شرح طبقات المعمارية
|
||||
|
||||
| الطبقة | الدور |
|
||||
|---|---|
|
||||
| **CDN / DNS** (اختياري) | تقديم الملفات الثابتة (صور، CSS، JS) بعيدًا عن السيرفرات الأساسية لتخفيف الحمل |
|
||||
| **Ghaymah Load Balancer** | يوزّع الـ 15,000 request/second على كل الحاويات المتاحة، ويستبعد أي حاوية فشلت في فحص `/health` |
|
||||
| **طبقة التطبيق (Auto-scaling Group)** | 39 حاوية تشغّل نفس كود التطبيق، بدون حالة (Stateless) — أي حاوية تقدر تخدم أي طلب |
|
||||
| **Valkey (Cache)** | يخزّن نتائج متكررة الطلب في الذاكرة لتقليل عدد المرات اللي التطبيق محتاج فيها يرجع لقاعدة البيانات |
|
||||
| **PgBouncer (Connection Pooler)** | يمنع كل حاوية من فتح اتصال منفصل بقاعدة البيانات — بيجمع الاتصالات في مجموعة مشتركة محدودة |
|
||||
| **PostgreSQL + Ghaymah Block Storage** | قاعدة البيانات الوحيدة اللي عندها حالة (Stateful) — بياناتها محفوظة على Block Storage مستقل عن دورة حياة الحاوية |
|
||||
| **Grafana / Uptime Kuma** | مراقبة اتجاه الموارد وحالة كل حاوية لحظيًا |
|
||||
|
||||
**لماذا الحاويات Stateless؟** عشان الـ Load Balancer يقدر يوزّع أي طلب على أي حاوية من غير ما يهتم "مين خدم الطلب اللي فات" — أي بيانات محتاجة تتحفظ (Session, User data) بتتخزن في Valkey أو PostgreSQL مش داخل الحاوية نفسها.
|
||||
|
||||
---
|
||||
|
||||
## 2. حساب عدد الحاويات المطلوبة
|
||||
|
||||
### المعطيات
|
||||
- الحمل الكلي: **15,000 request/second**
|
||||
- سعة الحاوية الواحدة: **500 request/second**
|
||||
- هامش أمان: **30%**
|
||||
|
||||
### طريقة الحساب
|
||||
|
||||
الهدف من هامش الأمان هو **عدم تشغيل أي حاوية على أقصى طاقتها بالكامل** — بيسيب مساحة للتعامل مع أي ارتفاع مفاجئ في الحمل (Traffic spike) من غير ما يحصل تعطّل.
|
||||
|
||||
**الخطوة 1: العدد الأساسي بدون هامش**
|
||||
```
|
||||
عدد الحاويات الأساسي = إجمالي الطلبات ÷ سعة الحاوية
|
||||
= 15,000 ÷ 500
|
||||
= 30 حاوية
|
||||
```
|
||||
|
||||
**الخطوة 2: إضافة هامش الأمان 30%**
|
||||
```
|
||||
عدد الحاويات النهائي = 30 × (1 + 0.30)
|
||||
= 30 × 1.30
|
||||
= 39 حاوية
|
||||
```
|
||||
|
||||
### ✅ النتيجة: **39 حاوية**
|
||||
|
||||
> ملاحظة: فيه طريقة حساب بديلة لنفس المفهوم — اعتبار إن كل حاوية بتشتغل بحد أقصى 70% من طاقتها بس (500 × 0.7 = 350 req/s فعّالة)، وده بيدّي `15,000 ÷ 350 ≈ 43` حاوية. الطريقتين صحيحتين مفاهيميًا (الهدف "هامش أمان")، لكن التفسير الأول (39 حاوية) هو الأقرب لصياغة "العدد + هامش 30%" في نص المهمة، فهو المعتمد هنا.
|
||||
|
||||
### جدول توضيحي لأحمال مختلفة (Auto-scaling Table)
|
||||
|
||||
| الحمل الحالي (req/s) | العدد الأساسي | العدد بعد هامش 30% |
|
||||
|---|---|---|
|
||||
| 5,000 | 10 | 13 |
|
||||
| 10,000 | 20 | 26 |
|
||||
| 15,000 | 30 | **39** |
|
||||
| 20,000 | 40 | 52 |
|
||||
|
||||
هذا الجدول هو أساس سياسة Auto-scaling: كل ما زاد الحمل الفعلي، تزيد المنصة عدد الحاويات تلقائيًا بنفس النسبة.
|
||||
|
||||
---
|
||||
|
||||
## 3. استراتيجية Cold Start للحاويات الجديدة
|
||||
|
||||
**المشكلة:** لما Auto-scaling يقرر يضيف حاوية جديدة فجأة (بسبب ارتفاع الحمل)، الحاوية الجديدة بتاخد وقت (Cold Start) قبل ما تبقى جاهزة فعليًا تستقبل طلبات — تحميل التطبيق، فتح اتصالات قاعدة البيانات، تسخين الكاش المحلي... إلخ. لو الـ Load Balancer وجّه طلبات ليها فورًا، ممكن تفشل أو تكون بطيئة جدًا.
|
||||
|
||||
### الاستراتيجية المقترحة
|
||||
|
||||
| # | الإجراء | الفائدة |
|
||||
|---|---|---|
|
||||
| 1 | **Minimum Warm Pool** — حافظ دايمًا على عدد أدنى من الحاويات شغالة (مثلًا 10 حاويات) حتى وقت الحمل المنخفض | يقلل الاعتماد على Cold Start في الحالات العادية؛ التوسع بيبقى غالبًا زيادة على حاويات موجودة أصلًا مش بداية من الصفر |
|
||||
| 2 | **Readiness Probe قبل استقبال الترافيك** | الحاوية الجديدة متتسجلش في الـ Load Balancer إلا بعد ما ترد بنجاح على فحص `/health` أو `/ready` — يمنع توجيه طلبات لحاوية لسه بتبدأ |
|
||||
| 3 | **صور Docker خفيفة ومبنية مسبقًا (Pre-built lightweight images)** | استخدام صور Alpine بدل الصور الكاملة، وبناء الطبقات (Layers) بترتيب يخلي الأجزاء المتغيرة بس تحتاج إعادة تحميل — يقلل وقت الـ pull والبدء |
|
||||
| 4 | **Connection Pool Warm-up عند البدء** | فتح اتصالات قاعدة البيانات (عبر PgBouncer) والكاش (Valkey) فورًا عند إقلاع الحاوية، قبل ما تستقبل أول طلب حقيقي |
|
||||
| 5 | **Predictive/Scheduled Scaling** | لو أوقات الذروة معروفة ومتكررة (مثلًا كل يوم الساعة كذا)، جدولة زيادة الحاويات مسبقًا بدل انتظار الحمل يرتفع فعليًا ثم رد الفعل |
|
||||
| 6 | **Gradual Traffic Ramp-up (Canary-style)** | بعد ما الحاوية الجديدة تجتاز فحص الصحة، وجّهلها نسبة صغيرة من الترافيك الأول (مثلًا 10%) وزوّدها تدريجيًا، بدل ما تستقبل حصتها الكاملة فورًا |
|
||||
| 7 | **Cooldown/Stabilization Window** | فترة انتظار قصيرة (دقيقة أو دقيقتين) بعد كل قرار توسّع قبل اتخاذ قرار توسّع جديد — يمنع "التذبذب" (Flapping) في عدد الحاويات |
|
||||
|
||||
### التسلسل الزمني المقترح لإضافة حاوية جديدة
|
||||
```
|
||||
قرار Auto-scaling (الحمل تجاوز العتبة)
|
||||
│
|
||||
▼
|
||||
سحب/تشغيل الصورة (Image pull - سريع لو الصورة خفيفة ومخزنة مسبقًا على العقدة)
|
||||
│
|
||||
▼
|
||||
بدء التطبيق + Connection Pool Warm-up
|
||||
│
|
||||
▼
|
||||
Readiness Probe ينجح
|
||||
│
|
||||
▼
|
||||
التسجيل في Load Balancer بحصة ترافيك صغيرة (10%)
|
||||
│
|
||||
▼
|
||||
زيادة الحصة تدريجيًا لحد الوصول لحصة كاملة عادية
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. استخدام Ghaymah Block Storage للـ Stateful Workloads
|
||||
|
||||
### ليه الحاويات نفسها مش مكان مناسب لتخزين البيانات؟
|
||||
الحاويات في المعمارية دي **Stateless بالتصميم** — ممكن تتقفل أو تتستبدل في أي وقت (Auto-scaling, إعادة نشر, فشل مفاجئ) من غير أي تحذير. أي بيانات محفوظة جوه الحاوية نفسها بتضيع فور ما الحاوية تتقفل.
|
||||
|
||||
### دور Block Storage
|
||||
**Ghaymah Block Storage** هو تخزين دائم (Persistent Volume) مستقل تمامًا عن دورة حياة أي حاوية معينة — بيتحط (Attach) على الحاوية اللي محتاجاه، ولو الحاوية دي اتقفلت أو اتستبدلت، الـ Volume بياناته باقية وممكن يتحط على حاوية جديدة.
|
||||
|
||||
### أهم الاستخدامات في هذه المعمارية
|
||||
|
||||
| الحالة | استخدام Block Storage |
|
||||
|---|---|
|
||||
| **قاعدة بيانات PostgreSQL** | ملفات البيانات (Data directory) بتتخزن على Volume منفصل، مش داخل حاوية قاعدة البيانات نفسها — لو الحاوية اتعاد تشغيلها أو اتستبدلت (تحديث نسخة مثلًا)، البيانات باقية |
|
||||
| **رفع ملفات المستخدمين (User uploads)** | لو التطبيق بيسمح برفع صور/ملفات، بتتخزن على Volume مشترك بدل تخزينها محليًا داخل حاوية واحدة (اللي ممكن تختفي وتاخد الملفات معاها) |
|
||||
| **أرشفة اللوجز طويلة المدى** | لوجز التطبيق التفصيلية اللي محتاجة تتحفظ لفترة أطول من عمر الحاوية |
|
||||
| **نسخ احتياطية (Backups)** | تصدير نسخ احتياطية دورية من قاعدة البيانات على Volume منفصل، مستقل عن أي Container instance |
|
||||
|
||||
### مبادئ أساسية للاستخدام الصحيح
|
||||
1. **فصل التخزين عن الحوسبة (Decouple storage from compute):** الحاوية تُعامل كموردة مؤقتة قابلة للاستبدال، والـ Volume هو مكان "الحقيقة الدائمة" للبيانات
|
||||
2. **حاوية واحدة فعّالة للكتابة في كل مرة** (لقواعد البيانات التقليدية) — لتفادي تعارض الكتابة المتزامنة على نفس الـ Volume
|
||||
3. **نسخ احتياطي دوري للـ Volume نفسه**، مش الاعتماد عليه كمصدر وحيد للبيانات
|
||||
4. **قياس الأداء (IOPS/Throughput)** المطلوب حسب حمل قاعدة البيانات — قواعد البيانات عالية الكتابة محتاجة Block Storage بأداء أعلى من مجرد تخزين ملفات ثابتة
|
||||
|
||||
### كيف يتكامل هذا مع باقي المعمارية
|
||||
```
|
||||
حاوية PostgreSQL (Stateless container, قابلة للاستبدال)
|
||||
│
|
||||
▼ (attach)
|
||||
Ghaymah Block Storage Volume (البيانات الفعلية، دائمة)
|
||||
```
|
||||
لو حاوية قاعدة البيانات احتاجت تُعاد تشغيلها (تحديث، صيانة، أو حتى فشل)، حاوية جديدة تتشغل وتاخد نفس الـ Volume المرفق — البيانات ما بتضيعش، وده الفرق الجوهري بين التعامل مع الـ 39 حاوية التطبيقية (Stateless، ممكن تتستبدل بحرية) وحاوية قاعدة البيانات (Stateful، البيانات لازم تتحفظ عبر Block Storage).
|
||||
المرجع في مشكلة جديدة
حظر مستخدم