المستوى المستهدف: متوسط — يفترض إنك بتشتغل على Kubernetes وتعرف HPA و YAML بشكل أساسي.
KEDA: scale workers من صفر لـ 50 بناءً على طول طابور Redis
لو عندك 8 worker pods شغّالين 24/7 بيعالجوا 4,000 task في اليوم بس، انت بتدفع لـ Kubernetes 7,500 ساعة CPU شهريًا في الفاضي. KEDA بيخلّيهم 0 لما الطابور فاضي، و50 لما يمتلئ، بصفر تعديل في كود الـ worker.
المشكلة باختصار
الـ Horizontal Pod Autoscaler الافتراضي في Kubernetes بيقيس CPU و memory بس. مشكلة الـ async workers إن استهلاكهم للـ CPU قليل (هم بيستنّوا I/O أغلب الوقت)، وانت محتاج تعرف "في كام task مستنّي في الطابور؟" مش "البودات شغّالة قد ايه؟".
سيناريو حقيقي من إنتاج: نظام معالجة صور لتطبيق e-commerce فيه 8 workers ثابتة. متوسط 4,000 صورة في اليوم بس Black Friday بيوصل 280K. الـ 8 workers بتقع تحت الضغط، الطلبات بتاخد 14 دقيقة بدل ثانيتين، وبيوصل شكاوى من 312 عميل في يومين.
المثال التقريبي للمبتدئ: كاشير السوبر ماركت
تخيل سوبر ماركت فيه 8 كاشير شغّالين دايمًا. الساعة 3 الصبح طابور الزبائن صفر، 8 كاشير قاعدين على بعض. الساعة 8 المساء فيه 80 زبون في الطابور و 8 كاشير مش كفاية، الزبائن بتمشي قبل ما تدفع.
KEDA هو المدير الذكي اللي بيبصّ على طابور الكاشير كل 30 ثانية:
- طابور صفر؟ يصرف الكاشير كلهم وما تدفعش رواتب.
- طابور 80 زبون؟ يستدعي 50 كاشير من الباك أوفيس في دقيقة.
- الزحمة هدت؟ يبدأ يصرفهم تدريجي بعد 5 دقائق هدوء.
الفكرة دي بالظبط هي scale-to-zero و event-driven autoscaling. النقطة الأساسية إن المقياس مش "الكاشير تعبان قد ايه" (CPU)، المقياس "الطابور طوله كام" (Redis list length).
التعريف العلمي لـ KEDA
KEDA اختصار Kubernetes Event-Driven Autoscaler. مشروع CNCF حصل على Graduated status في أغسطس 2023، بدأ كشراكة بين Microsoft و Red Hat. بيعمل extend للـ HPA الأصلي بحيث يقرا metrics من 70+ مصدر خارجي: Redis, Kafka, RabbitMQ, AWS SQS, Prometheus, PostgreSQL, GitHub Actions، إلخ.
المعمارية الداخلية فيها 3 مكونات:
- KEDA Operator: controller بيراقب objects من نوع
ScaledObjectويترجمها لـ HPA objects تقليدية. - Metrics Adapter: بيقدّم metrics للـ external metrics API الخاص بـ Kubernetes، فالـ HPA بيستخدمها كأنها CPU عادي.
- Scaler: مكوّن صغير لكل مصدر، بيتكلم مع المصدر الخارجي ويرجّع رقم (طول الطابور مثلًا).
الفرق الجوهري عن HPA الافتراضي: KEDA بيقدر يعمل scale-to-zero (من 0 لـ N)، الـ HPA الأصلي حدّه الأدنى 1 pod ثابت.
الإعداد الكامل في 30 سطر
1. تثبيت KEDA على Kubernetes 1.30
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda \
--create-namespace \
--version 2.15.1
التثبيت بياخد دقيقتين وبيشغّل 3 pods في namespace keda: operator + metrics-server + admission-webhooks.
2. تعريف ScaledObject لـ Redis Queue
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: image-worker-scaler
namespace: workers
spec:
scaleTargetRef:
name: image-processor # اسم الـ Deployment الموجود
minReplicaCount: 0 # ينزل لصفر فعلاً
maxReplicaCount: 50 # السقف وقت الذروة
pollingInterval: 30 # كل 30 ثانية يفحص الطابور
cooldownPeriod: 300 # 5 دقائق هدوء قبل scale-down
triggers:
- type: redis
metadata:
address: redis-master.cache:6379
listName: image-jobs
listLength: "20" # كل pod يتحمل 20 رسالة
activationListLength: "5" # تحت 5 يفضل صفر
شرح الحقول الحرجة:
listLength: "20"- الـ HPA بيحسب:desiredReplicas = ceil(currentQueueLen / 20). لو الطابور 100، يبقى 5 pods.activationListLength: "5"- الـ scale-from-zero بيحصل لما الطابور ≥ 5. تحت كده يفضل صفر. ده بيمنع الـ flapping.cooldownPeriod: 300- بعد ما الطابور يفضى، KEDA بيستنّى 5 دقائق قبل ما ينزّل آخر pod لصفر، عشان ما يعملش thrashing لو جاءت رسالة فجأة.
3. التطبيق والتحقق
kubectl apply -f scaledobject.yaml
kubectl get hpa -n workers
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# keda-hpa-image-worker Deployment/image-processor 0/20 1 50 0
# اختبار: ضخّ 100 رسالة في الطابور
redis-cli -h redis-master.cache LPUSH image-jobs $(seq 1 100 | xargs -I{} echo "job-{}")
# بعد 30 ثانية:
kubectl get pods -n workers
# image-processor-xxx Running (5 pods)
الأرقام المقاسة من إنتاج فعلي
على cluster GKE بـ 24 microservice، بعد 30 يوم تشغيل في إنتاج e-commerce عربي:
- متوسط pods شغّالة: 8 ثابت → 1.4 (انخفاض 82%).
- ذروة Black Friday: 8 (مش كفاية) → 47.
- فاتورة CPU شهريًا للـ workers: $312 → $58 (توفير $254 شهريًا).
- P95 task latency وقت الذروة: 14 دقيقة → 38 ثانية (تحسّن 22 ضعف).
- Cold start delay من صفر لأول pod جاهز: 4.2 ثانية (مع image مخزّن في node cache).
التوفير الفعلي: 81% من فاتورة compute للـ workers، مع تحسّن latency وقت الضغط. الافتراض: image الـ container مش أكبر من 200MB ومخزّن locally على معظم الـ nodes.
4 Trade-offs خفية لازم تعرفها
- Cold start tax: لما الطابور يبدأ من صفر، أول رسالة بتستنّى pod يقوم. على image 200MB في node فاضي، 4-8 ثواني. مش مناسب لو الـ SLA تحت ثانية.
- Polling overhead: كل 30 ثانية، KEDA بيعمل
LLENعلى Redis. على cluster كبير بـ 200 ScaledObject، ده 6.6 query/ثانية ثابت على الـ Redis. خفّف الـpollingIntervalلـ 60 لو ما تحتاجش استجابة سريعة. - Activation threshold gotcha: لو حطّيت
activationListLength: "1"والـ producer بيبعت رسالة كل 6 دقائق، KEDA هيعمل scale-up و scale-down في حلقة لانهائية. خلّيها ≥ 5، أو زوّد الـcooldownPeriod. - State loss في scale-down: لو الـ worker شايل state في الذاكرة (cache، open connections)، scale-to-zero بيمسحه كل مرة. الحل: حطّ الـ state في Redis نفسه، أو شغّل بـ
minReplicaCount: 1بدل صفر.
متى لا تستخدم KEDA أصلاً
- Workloads ثابتة الحمل (web API بـ traffic منتظم 24/7): HPA على CPU كافي ومش محتاج تعقيد KEDA.
- SLA تحت 500ms من أول رسالة: cold start هيكسره. خلّي
minReplicaCount: 1على الأقل. - Workers بـ in-memory cache كبير (model AI 4GB مثلًا): scale-to-zero هيخسّر الـ cache كل مرة وهيعمل cold start مدمّر. هنا KEDA بيضرّك بدل ما يفيد.
- Cluster صغير (أقل من 5 microservice): التعقيد الإضافي من إضافة operator ومراقبته مش بيستاهل التوفير.
الخطوة التالية
افتح أكبر deployment workers عندك، شغّل kubectl top pods -n <ns> ولاحظ كام pod قاعد بـ CPU أقل من 5% طول الـ 24 ساعة. لو > 50% منهم كده، انت مرشّح ممتاز لـ KEDA. ابدأ بـ minReplicaCount: 1 (مش صفر) كخطوة أولى آمنة لمدة أسبوع، شوف الـ cold start tolerance، وبعدها انزل لصفر بأمان.
المصادر
- KEDA Official Documentation 2.15: https://keda.sh/docs/2.15/
- CNCF Graduation Announcement (August 2023): https://www.cncf.io/announcements/2023/08/24/cloud-native-computing-foundation-announces-keda-graduation/
- KEDA Redis Lists Scaler Reference: https://keda.sh/docs/2.15/scalers/redis-lists/
- Kubernetes Horizontal Pod Autoscaler Docs: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
- External Metrics API Specification: External Metrics API Design Proposal