لو Kubernetes HPA بيعمل scale عند 80% CPU بس الـ messages في الـ queue بتتراكم لآلاف الرسائل، مشكلتك إن الـ CPU مش المقياس الصحيح للـ workloads اللي بتستنى أحداث.
المشكلة باختصار
CPU-based autoscaling بيشتغل صح لما الـ load مرتبط مباشرةً بالـ CPU. لكن الـ workloads الحديثة — workers بتقرأ من Kafka، مستهلكين RabbitMQ، معالجات webhooks، consumers من SQS — بتقضي معظم وقتها في I/O wait. ممكن CPU يكون 20% بينما الـ queue فيها 50 ألف رسالة مستنية. HPA الافتراضي مش هيعمل scale، والـ SLA هيكسر قدام عينيك.
تخيّل مطعم فيه سفرجي كسلان
علشان نفهم المشكلة بدون تعقيد: تخيّل مطعم فيه ٣ سفرجية. الطلبات بتتكتب على ورقة وبتتعلّق في الـ kitchen. المدير قاعد يبص على الـ CPU بتاع السفرجية — يعني مدى إرهاقهم الجسدي. الـ CPU عندهم 20% لأنهم معظم الوقت بيستنوا الطباخ يجهّز الأكل. المدير يقرّر: "مفيش حاجة، كله تمام". بس في الحقيقة، عدّاد الطلبات وصل ٢٠٠ طلب مستنى، والزبون قاعد ٤٥ دقيقة.
المشكلة مش في السفرجية، المشكلة في إن المقياس الغلط. لازم المدير يبص على طابور الطلبات نفسه، مش على إرهاق السفرجي. ده بالظبط الفرق بين HPA التقليدي و KEDA.
ليه CPU مش مقياس كافي لـ workers (علمياً)
افرض إن عندك worker بيقرأ من AWS SQS. كل رسالة بتاخد 200ms معالجة: منهم 160ms I/O wait على external API، و 40ms CPU فعلي. لو 3 pods بتعالج 3,000 رسالة/دقيقة، كل pod بيدوّر 16 رسالة/ثانية ويوصل لـ CPU 15% بس.
الـ user مش بيحس بالـ CPU. اللي بيحسه هو إن الطلب اللي عمله قبل ٨ دقايق لسه في الـ queue. لو HPA متضبط عند 70% CPU، مش هيعمل scale أبداً. المشكلة مش في الـ CPU — المشكلة في queue depth بالظبط.
KEDA: المقياس الصحيح للأحداث
KEDA اختصار Kubernetes Event-driven Autoscaling. مشروع graduated من CNCF. بيضيف طبقة فوق HPA تقدر تقرأ من أكتر من 70 مصدر: Kafka, RabbitMQ, SQS, Redis Streams, Prometheus queries, Azure Service Bus, PostgreSQL، وغيرهم كتير. الفكرة بسيطة: انت بتعرّف ScaledObject بيقول "لما الـ queue فيها X رسالة، اعمل scale لـ Y pods".
التثبيت في أمرين
helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda \
--namespace keda --create-namespaceبعد دقيقة بالكتير، هتلاقي keda-operator و keda-metrics-apiserver شغّالين في namespace اسمه keda.
مثال شغّال: scaling على RabbitMQ queue
الـ ScaledObject ده بيخلي deployment اسمه order-worker يعمل scale بناءً على عدد الرسائل في queue اسمها :