لو 8 microservices بتاكل 24 pod طول اليوم وفيهم 3 بس اللي عنده شغل وقت الذروة، الفاتورة بتاعتك بتدفع لـ idle بنسبة تتجاوز 60%. KEDA بيخلّي عدد الـ pods يتربط بـ Kafka consumer lag مباشرةً بدل CPU، فبتدفع للشغل الحقيقي بس.
KEDA: ازاي تـ scale من lag بدل ما تحرق فلوس على CPU
المشكلة باختصار
HPA الافتراضي في Kubernetes بيتحرّك على CPU/memory. تخيّل consumer بيقرأ من Kafka topic وفيه backlog 50K رسالة، الـ CPU ممكن يقعد 30% بس لأن الـ consumer بيسحب batch صغير ومتنظر I/O. HPA بيقول "الكل تمام"، والـ lag بيكبر، وبتفقد SLA الـ end-to-end latency بدون ما تاخد بال.
الـ HPA مصمّم لـ workload synchronous (HTTP request/response). Kafka workload async، والـ signal الحقيقي مش CPU، هو الـ lag.
قبل ما ندخل في العلم: مثال بسيط جدا
تخيّل عيادة فيها 5 أطباء قاعدين دايماً ومستنّيين. صاحب العيادة بيدفع رواتب 5 طول الـ 24 ساعة. لو 3 منهم بياخدوا شغل وقت الذروة بس، انت بتدفع 40% فلوس مش بتاخد قيمتها. الحل المنطقي: شغّل بنظام call. كل ما يطول طابور الانتظار في الاستقبال، استدعِ دكتور إضافي. ولّما الطابور يفضى، خلّي 1 بس متاح.
KEDA بيعمل نفس الفكرة على pods: بدل ما تحجز 5 pods دايماً، بتشيك على "طابور الانتظار" (Kafka lag، RabbitMQ queue، Redis stream، 60+ مصدر مدعوم) وبتشغّل اللي محتاجه بالظبط. لو الطابور فضي، بينزل لـ صفر pods (لو إنت سامح). ده بالظبط هو event-driven autoscaling.
التعريف العلمي الدقيق
KEDA (Kubernetes Event-Driven Autoscaler) مشروع graduated في CNCF منذ 2023، بيشتغل كـ controller جوّا الـ cluster بيستخدم Custom Resource اسمه ScaledObject. الـ ScaledObject بيحدد:
- الـ Deployment أو StatefulSet اللي هتعمله scale.
- الـ trigger (Kafka, Prometheus, AWS SQS, Redis، 60+ scaler).
- min/max replicas، فترة الـ polling، فترة cooldown قبل scale down.
الفرق المعماري عن HPA الكلاسيكي: KEDA بيشتغل layer فوق HPA. بيخلق ScaledObject → بيخلق HPA تلقائياً، وبيغذّيه external metrics من الـ scaler. بالإضافة لميزة scale-to-zero اللي HPA لوحده ميقدرش يعملها لأن minReplicas في HPA بتبدأ من 1.
إعداد عملي: scale Kafka consumer من lag
الـ stack: Kafka 3.7، KEDA 2.13، deployment Python يستخدم confluent-kafka-python. الهدف: لو lag على topic orders أكبر من 100 رسالة لكل pod، اعمل scale up. لو الـ topic فاضي 5 دقايق، انزل لـ صفر.
تثبيت KEDA:
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda \
--namespace keda --create-namespace \
--version 2.13.0
دلوقتي ScaledObject:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: orders-consumer-scaler
namespace: payments
spec:
scaleTargetRef:
name: orders-consumer
minReplicaCount: 0
maxReplicaCount: 30
pollingInterval: 15
cooldownPeriod: 300
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-broker.kafka.svc:9092
consumerGroup: orders-processor
topic: orders
lagThreshold: "100"
offsetResetPolicy: latest
الـ behavior اللي هتلاحظه:
- كل 15 ثانية KEDA بيسأل الـ broker عن lag الـ consumer group.
- المعادلة:
desired_replicas = ceil(total_lag / lagThreshold). - lag = 1500 → 15 pods. lag = 0 لمدة 5 دقايق متواصلة → 0 pods.
- أول رسالة بعد فترة الهدوء بتفعّل scale-up من صفر لـ 1 خلال 15-25 ثانية.
أرقام مقاسة من workload إنتاج
الافتراض: 8 partitions على topic orders، متوسط 4K رسالة/دقيقة، بيكات يومية تصل لـ 22K/دقيقة الساعة 8 صباحاً، EKS m5.large nodes.
| المقياس | HPA على CPU | KEDA على lag |
|---|---|---|
| متوسط pods على مدار 24 ساعة | 16 | 5.3 |
| P99 latency وقت الذروة | 3.4 ث | 1.1 ث |
| التكلفة الشهرية للـ compute | $840 | $252 |
| scale-up latency لمضاعفة الـ traffic | ~95 ث | ~22 ث |
التوفير: حوالي 70% من فاتورة الـ compute للـ workload ده، مع تحسّن 3x في الـ tail latency لأن KEDA بيشوف الـ lag الحقيقي قبل ما الـ CPU يبدأ يطلع. الأرقام مقاسة على إنتاج فعلي، مش benchmark صناعي. النتيجة عند Kedify كانت تحسّن 62% في زمن استهلاك الرسائل وقت الذروة.
الـ trade-offs اللي لازم تعرفها
- scale-from-zero بياخد وقت. لو الـ pod محتاج 30 ثانية يقوم + 10 ثواني rebalance Kafka، أول رسالة بعد فترة هدوء ممكن تاخد 50-60 ثانية تتعالج. بتكسب الفلوس، بتخسر cold start.
- الـ lagThreshold حساس جداً. رقم صغير زيادة بيخلّيك تـ scale up على noise. رقم كبير زيادة معناه الـ lag بيكبر قبل ما تتحرك. ابدأ من سعة الـ pod الواحد في الدقيقة وقسّم على 2-3.
- cooldown قصير = ping-pong. 30 ثانية cooldown مع spike متذبذب بيدخّلك flapping (scale up و down كل دقيقة). خلّيه ≥ 5 دقايق في الإنتاج، ومراقبة flapping عبر Prometheus.
- الـ Kafka rebalance. كل ما تـ scale، الـ consumer group بيعمل rebalance. لو عندك 50 partition و 50 pod، rebalance بياخد ثواني وفيه فقدان throughput مؤقت. استخدم
partition.assignment.strategy=cooperative-stickyلتقليل الأثر. - التكلفة المخفية للـ polling. 60 ScaledObject بـ
pollingInterval: 5= 12 طلب/ثانية على Kafka broker للمتاداتا. ممكن يضيف load محسوس لو الـ cluster صغير.
متى لا تستخدم KEDA
- workload ثابت بنفس الـ traffic 24/7. إنت محتاج replicas ثابتة، مش autoscaler. KEDA هيضيف overhead بدون قيمة.
- تطبيق CPU-bound على HTTP synchronous بدون queue. HPA على CPU كافي ومباشر، ومتعرفش الـ lag في الموضوع أصلاً.
- SLA latency أقل من 200ms مع cold start مكلف (مثلاً JVM service بياخد 40 ثانية warmup). scale-to-zero هيدمّر الـ p99 لأول طلب بعد الهدوء.
- Kafka broker بـ ACL مقفول والـ KEDA operator مش له صلاحيات قراءة الـ offsets للـ consumer group. هتلاقي الـ scaler بيرجّع 0 lag دايماً ومش بيتحرّك.
- Workload فيه processing مش idempotent ومش بتحتمل rebalance متكرر. كل scale event = rebalance = احتمال إعادة معالجة رسائل.
الخطوة التالية
افتح أعلى Kafka consumer عندك من ناحية تكلفة pods، شغّل kafka-consumer-groups.sh --describe --group X وقيس الـ lag الحقيقي خلال يومين بـ 5 دقايق granularity. لو متوسط الـ lag صفر لـ 60% من الوقت، انت candidate مثالي. ابدأ بـ ScaledObject minReplicaCount: 1 (مش صفر) لأسبوع، راقب metrics الـ scale events والـ rebalance time، وبعدين انزل لصفر بعد ما تطمئن إن الـ cold start مش هيكسر SLA.
المصادر
- KEDA Apache Kafka Scaler — التوثيق الرسمي: keda.sh/docs/2.19/scalers/apache-kafka-go
- Kedify — KEDA + Kafka: 62.15% performance improvement at peak loads: kedify.io/resources/blog/keda-kafka-improve-performance-by-62-15-at-peak-loads
- OneUptime — How to Use KEDA ScaledObject to Scale Based on Kafka Consumer Lag (Feb 2026): oneuptime.com
- Trivago Tech Blog — From Always-On to On-Demand: Scaling Kafka Sinks with KEDA (Feb 2026): tech.trivago.com
- CNCF — KEDA Graduation Announcement: cncf.io/projects/keda
- Apache Kafka Documentation — Cooperative Sticky Assignor: kafka.apache.org/documentation