مستوى المقال: محترف — يفترض إنك عارف Kubernetes، والفرق بين requests وlimits، وأساسيات Linux cgroups.
لو خدمتك بطيئة والـ p99 latency بيقفز، وفي نفس الوقت لوحة المراقبة بتقول إن استهلاك المعالج على العقدة أقل من 40%، غالبًا المشكلة مش في السيرفر. دي حصّة CFS بتخنق الحاوية. المقال ده هيوريك إزاي تتأكد بالأرقام، وإزاي تصلحها بدون ما تكسر حاجة تانية.
الـ CPU Throttling في Kubernetes: ليه خدمتك بطيئة والمعالِج نصّه فاضي
المشكلة باختصار
الـ CPU limit في Kubernetes مش سقف ناعم. هو سقف صارم بيتفرض كل 100 مللي ثانية. لو خدمتك خلّصت حصّتها قبل ما تنتهي النافذة، الكيرنل بيوقّف كل خيوطها لحد بداية النافذة اللي بعدها. الانتظار ده اسمه throttling. النتيجة: latency عالي مع استغلال معالج يبان منخفض. فخ كلاسيكي بيضيّع ساعات في التشخيص الغلط.
ليه بيحصل الـ throttling أصلاً
تخيّل صنبور ماء بيفتح دقيقة واحدة بس كل ساعة. لو ملّيت كل جراكنك في أول 10 دقايق، مش هتقدر تاخد نقطة تانية غير الساعة الجاية، حتى لو الخزان مليان. الصنبور هنا هو حصّتك من المعالج، والساعة هي نافذة الجدولة.
علميًا: Kubernetes بيترجم الـ CPU limit إلى إعدادات CFS bandwidth في الـ cgroup. النافذة الافتراضية cpu.cfs_period_us بتساوي 100000 ميكروثانية، يعني 100 مللي ثانية. والحصّة cpu.cfs_quota_us بتتحسب كالتالي:
quota = (CPU limit بالـ millicores / 1000) * 100000 ميكروثانية
limit = 500m -> quota = 50000us (50ms شغل لكل 100ms)
limit = 1000m -> quota = 100000us (100ms شغل لكل 100ms)
لو استهلكت الحصّة قبل نهاية النافذة، الحاوية بتتوقف حتى النافذة اللي بعدها. المهم إن ده سقف على القمة (peak) مش على المتوسط. تطبيق بيعمل burst قصير ممكن يتخنق حتى لو متوسط استهلاكه بعيد جدًا عن الحد.
الفخ الأكبر: التطبيق متعدد الخيوط
ده السبب اللي بيخلّي ناس كتير تتفاجأ. الحصّة بتتحسب عبر كل خيوط الحاوية مجتمعة، مش لكل خيط. لو عندك خدمة بأربع خيوط شغّالة وحدّها limit = 1، الأربع خيوط بيستهلكوا الـ 100ms المسموحة في 25ms wall-clock بس. بعدها الحاوية بتتخنق 75ms كاملة من كل نافذة.
سيناريو واقعي: خدمة Go على 8-core node بحدّ 500m. الـ runtime بيشوف 8 أنوية فبيفتح 8 خيوط للـ GC والجدولة. الحصّة 50ms بس بتتوزّع على 8 خيوط، فبتخلص في أقل من 7ms. النتيجة قفز الـ p99 من 20ms لأكثر من 200ms تحت الحمل، مع throttling حوالي 60% من النوافذ.
إزاي تكتشفه بالأرقام
متعتمدش على الإحساس. اقرأ العدّاد مباشرة. جوّا الحاوية على cgroup v2: