تخطيط السعة والتوسع التلقائي

قياس الاستخدام والإشباع

18 دقيقة الدرس 2 من 27

قياس الاستخدام والإشباع

تخطيط السعة بدون قياس ليس سوى تخمين. المقاييس التي تجمعها — وطريقة تفسيرها — هي الفارق بين قرار توسع واثق وبين أزمة في الساعة الثانية صباحاً. يتناول هذا الدرس الإشارات الدقيقة المهمة لقرارات السعة على نطاق الإنتاج: ما الذي تقيسه، وكيف تجمعها بشكل موثوق، والتفسير العملي الذي يميز المشغل الجيد عن الاستثنائي.

منهج USE: إطار لتحليل الموارد

يمنحك منهج USE (الاستخدام، الإشباع، الأخطاء) الذي وضعه Brendan Gregg قائمةً تدقيق منهجية لكل مورد مادي أو افتراضي — وحدات المعالجة، الذاكرة، الأقراص، بطاقات الشبكة، حصص موارد Kubernetes، وحدود خدمات السحابة. طبّقه على كل مورد قبل أن تستنتج أن النظام "يعمل بصحة جيدة".

  • الاستخدام (Utilization): ما نسبة سعة المورد المستهلكة خلال فترة زمنية؟ الاستخدام المرتفع ليس سيئاً بالضرورة، لكنه يقلص هامش الأمان.
  • الإشباع (Saturation): هل يتراكم العمل في طابور لأن المورد لا يستطيع خدمته فوراً؟ الإشباع هو المؤشر المبكر لتدهور زمن الاستجابة — يظهر قبل ارتفاع p99 بوقت كافٍ.
  • الأخطاء (Errors): هل تفشل الطلبات أو العمليات على مستوى المورد (إعادة إرسال TCP، أخطاء قراءة القرص، إنهاء العمليات بسبب نفاد الذاكرة، استدعاءات API مقيّدة)؟
لماذا الإشباع أهم من الاستخدام: وحدة معالجة عند 70% استخدام مع طابور انتظار بطول 0 تعمل بشكل جيد. وحدة معالجة عند 55% استخدام مع عمق طابور انتظار مستمر بمقدار 4 قيد تدهور زمن الاستجابة بالفعل لكل عملية تتنافس على الدورات. اقرن دائماً الاستخدام بإشارة الإشباع المقابلة له.

المعالج: الإشارات التي تهم

نسبة استخدام المعالج المجردة مفرطة الاستخدام وغير محددة المعنى. على المستوى المتقدم تتابع هذه الإشارات معاً:

  • node_cpu_seconds_total{mode="idle"} — اشتق الاستخدام كـ 1 - rate(idle[5m]) لكل وحدة معالجة ثم اجمعها. التقسيم حسب الوضع (user, system, iowait, steal) يكشف سبب انشغال المعالج.
  • سرقة وقت المعالج (mode="steal") — على الأجهزة الافتراضية السحابية يكشف هذا تزاحم مضيفي hypervisor. قيمة steal فوق 5% تعني أن الجهاز الافتراضي الخاص بك مقيَّد من قبل المضيف لا من قبل حمل عملك.
  • طول طابور الانتظارnode_load1 وnode_load5 وnode_load15. قسّمها على عدد وحدات المعالجة. نسبة تتجاوز 1.0 باستمرار تعني أن المعالجات مشبعة.
  • تقنين CFS — في Kubernetes، container_cpu_cfs_throttled_seconds_total يحسب دورات المعالج التي حُرم منها الحاوي لأنه بلغ حصة CGroup. نسبة تقنين عالية مع استخدام معتدل على مستوى العقدة تعني أن لديك حدوداً غير كافية، لا مشكلة سعة على مستوى العقدة.
# PromQL: استخدام المعالج لكل عقدة (1 = 100%) 1 - avg by(node) ( rate(node_cpu_seconds_total{mode="idle"}[5m]) ) # PromQL: نسبة تقنين CFS للحاوي — كاشف نمط مضاد للسعة sum by (namespace, pod, container) ( rate(container_cpu_cfs_throttled_seconds_total[5m]) ) / sum by (namespace, pod, container) ( rate(container_cpu_cfs_periods_total[5m]) ) # سطر الأوامر: طابور الانتظار الفوري على العقدة vmstat -w 2 10 # سطر الأوامر: توزيع استخدام المعالج بما فيه steal mpstat -P ALL 5 3

الذاكرة: الاستخدام كذبة بدون سياق

مقاييس الذاكرة مضللة بشكل فريد. يستخدم نواة Linux الذاكرة الحرة بقوة للتخزين المؤقت للصفحات، مما يجعل "الذاكرة المستخدمة" رقماً مضللاً. الإشارات التي تدل فعلاً على ضغط السعة هي:

  • الذاكرة المتاحة (node_memory_MemAvailable_bytes) — هذا هو تقدير النواة نفسها لكمية الذاكرة التي يمكن تحريرها تحت الضغط دون تبديل. هذا ما يجب أن تنبّه عليه، ليس MemFree.
  • أخطاء الصفحة الرئيسية / نشاط التبديلnode_vmstat_pgmajfault وnode_memory_SwapUsed_bytes. أي استخدام مستمر للتبديل في حمل عمل مُحوسب إشارةُ إشباع؛ زمن الاستجابة متدهور بالفعل.
  • أحداث إنهاء العملية بسبب نفاد الذاكرةkube_pod_container_status_last_terminated_reason{reason="OOMKilled"}. كل عملية إنهاء هي حدث إشباع ذاكرة تأثر به حركة المرور الحقيقية.
  • مجموعة العمل مقابل RSS — يستخدم Kubernetes container_memory_working_set_bytes (ليس RSS) لقرارات الإخلاء وإنهاء العملية. أنبّه عند اقتراب مجموعة العمل من حد ذاكرة الحاوي.
فخ "تسرب الذاكرة مقابل الذاكرة المؤقتة": حاوي يتزايد فيه حجم مجموعة العمل بثبات على مدى ساعات قد يكون لديه تسرب ذاكرة — أو ربما يسخّن فقط ذاكرة مؤقتة للاستعلامات. قبل رفع حادثة من الأولوية الثانية، تحقق مما إذا كان النمو يستقر وما إذا كانت أحداث الإخلاء أو جمع القمامة مترابطة. ارسم مجموعة العمل مع مدة توقف جمع القمامة (JVM: jvm_gc_pause_seconds_sum) أو مقاييس وقت التشغيل المعادلة.

إدخال/إخراج القرص: الإنتاجية والـ IOPS والتأخير معاً

قرص مشبع على مستوى IOPS قد يكون لديه إنتاجية منخفضة (قراءات عشوائية صغيرة كثيرة)، والعكس صحيح. قرارات السعة تتطلب الأبعاد الثلاثة معاً:

  • node_disk_io_time_seconds_total — كسر الوقت الذي كان فيه الجهاز مشغولاً (rate على 1m يعطي الاستخدام من 0 إلى 1). فوق 0.8 يعد مخاطرة إشباع.
  • node_disk_read_bytes_total / node_disk_written_bytes_total — الإنتاجية؛ قارن مع حدود الجهاز المنشورة.
  • متوسط تأخير القراءة = node_disk_read_time_seconds_total / node_disk_reads_completed_total. فوق 1 ميلي ثانية لـ NVMe أو 10 ميلي ثانية لـ EBS الشبكي يشير إلى الإشباع.
# PromQL: استخدام القرص (0-1) لكل جهاز لكل عقدة rate(node_disk_io_time_seconds_total{device!~"loop.*"}[5m]) # PromQL: متوسط تأخير الكتابة بالميلي ثانية ( rate(node_disk_write_time_seconds_total[5m]) / rate(node_disk_writes_completed_total[5m]) ) * 1000 # سطر الأوامر: استخدام القرص الفوري، IOPS، توزيع التأخير iostat -xz 2 5 # سطر الأوامر: تحديد العملية التي تسبب ضغط القرص iotop -o -P

الشبكة: النطاق الترددي وفقدان الحزم وإشباع الاتصالات

يتجلى إشباع الشبكة بثلاثة أوجه: استنفاد النطاق الترددي، استنفاد جدول الاتصالات، وعواصف إعادة الإرسال. كل منها يتطلب معالجة مختلفة.

  • استخدام النطاق الترددي: rate(node_network_transmit_bytes_total[5m]) * 8 للحصول على بت/ثانية. استخدام مستدام فوق ~60% من الخط الأساسي قد يؤدي إلى تقنين صامت.
  • معدل إعادة الإرسال: rate(node_netstat_Tcp_RetransSegs[5m]). فوق 0.1% من إجمالي القطع يستحق التحقيق — يشير إلى فقدان حزم أو إشباع مخزن الاستقبال على الطرف البعيد.
  • استنفاد Conntrack: node_nf_conntrack_entries / node_nf_conntrack_entries_limit. عند تجاوز هذه النسبة 0.8، تبدأ اتصالات TCP الجديدة بالفشل. في Kubernetes، هذا يسقط حركة المرور بصمت بينما تبدو CPU والذاكرة بخير — حالة الصحة الكاذبة الكلاسيكية.
USE Method Signal Map CPU Utilization: 1 - idle rate mode split: user / system / steal Saturation: run-queue / CPU node_load1 / nproc > 0.7 = alert Errors: CFS throttle ratio throttled / total periods > 5% Memory Utilization: working set bytes vs container limit (not RSS) Saturation: MemAvailable low major faults, swap activity Errors: OOMKilled pods kube_pod_container_status_* Network / Disk Utilization: bytes/s vs link speed disk: io_time rate vs 1.0 Saturation: conntrack ratio disk: avg latency (ms) Errors: retransmit rate disk: I/O errors, SMART events Utilization Saturation Errors Apply USE to every resource: Disk, Network, Pod CPU/Memory limits, Node allocatable, Cloud API quotas
خريطة إشارات منهج USE عبر المعالج والذاكرة وموارد الشبكة والقرص — لكل فئة إشارات استخدام وإشباع وأخطاء مميزة.

إشارات السعة الخاصة بـ Kubernetes

يضيف Kubernetes طبقة من الموارد الافتراضية فوق إشارات نظام التشغيل. يجب أن تكون كلتا الطبقتين في صحة جيدة؛ يمكن أن تبدو العقدة غير مستغلة على مستوى نظام التشغيل بينما تكون مُفرطة في التعيين على مستوى الجدولة.

  • ضغط الموارد القابلة للتخصيص في العقدة: عندما تتجاوز طلبات الموارد الموارد القابلة للتخصيص، لا تستطيع الحاويات الجديدة الجدولة — هذا نفاد سعة حتى لو كان الاستخدام الفعلي للمعالج 40%.
  • انتهاكات ميزانية اضطراب الحاوية: مجموعة مشبعة لا تستطيع إخلاء العقد للترقيات هي مشبعة تشغيلياً بغض النظر عن مقاييس المعالج.
  • استخدام حصة مساحة الأسماء: مقاييس kube_resourcequota تتبع الحصة المحددة والمستخدمة لكل مساحة أسماء.
# kubectl: فحص الموارد القابلة للتخصيص مقابل المطلوبة على مستوى العقدة kubectl describe nodes | grep -A 6 "Allocated resources" # kubectl: إيجاد الحاويات بدون طلبات موارد (غير مرئية للجدولة) kubectl get pods -A -o json | \ jq '.items[] | select(.spec.containers[].resources.requests == null) | {name: .metadata.name, ns: .metadata.namespace}' # PromQL: نسبة الإفراط في تعيين المعالج للعقدة sum by (node) ( kube_pod_container_resource_requests{resource="cpu", unit="core"} ) / sum by (node) ( kube_node_status_allocatable{resource="cpu"} )

الإشارات الذهبية الأربع في سياق السعة

تُربط الإشارات الذهبية الأربع لـ Google (زمن الاستجابة، حركة المرور، الأخطاء، الإشباع) مباشرةً بقرارات السعة. الفكرة الأساسية هي أن الإشباع يتنبأ بالتدهور المستقبلي بينما تُبلغ الإشارات الثلاث الأخرى عن الحالة الراهنة. ابنِ لوحات سعة بحيث تُوضع إشارات الإشباع فوق إشارات زمن الاستجابة — تصرف قبل أن يشعر العملاء بالتأثير.

  • حركة المرور — الطلبات في الثانية أو الرسائل في الثانية هي إشارة الطلب. السعة = العرض؛ حركة المرور = الطلب. تتبع حجوم p50 و p90 و p99 لحركة المرور، لا المتوسطات فقط.
  • الإشباع — استخدم إشارات الإشباع لكل مورد الموضحة أعلاه. نتيجة الإشباع الإجمالية لخدمة ما هي أعلى إشباع عبر جميع الموارد التي تعتمد عليها.
  • زمن الاستجابة — تأخيرات p99 و p999 هي مؤشرات متأخرة للإشباع. إذا كنت ترى بالفعل تدهوراً في p99، فأنت تجاوزت السعة. استخدم الإشباع لتشغيل التوسع قبل 5-10 دقائق.
  • الأخطاء — معدلات 5xx والمهل الزمنية تؤكد أن الإشباع تحول إلى تأثير مرئي للمستخدم.
الممارسة الإنتاجية — أهداف هامش الأمان حسب المستوى: تُبقى خدمات المستوى الأول (حرجة للإيرادات) عادةً دون 60% استخدام على كل بُعد عند الذروة. خدمات المستوى الثاني تستخدم 70-75%. قد تصل أدوات المستوى الثالث (الأدوات الداخلية) إلى 85%. توجد هذه الهوامش لاستيعاب ارتفاعات حركة المرور المفاجئة ومنح مقاييس التوسع التلقائي وقتاً للتفاعل. حدّد هذه SLOs صراحةً في وثائق مراجعة السعة — لا تتركها ضمنية.

جمع المقاييس بشكل موثوق: الأخطاء الإنتاجية

لبنية تحتية للقياس نفسها أوضاع فشل تفسد بيانات السعة:

  • فترة الاستطلاع مقابل نافذة التنبيه: الاستطلاع الافتراضي في Prometheus هو 15 ثانية؛ HPA يستخدم تزامن 30 ثانية. إذا كانت نافذة التنبيه [1m] وفترة الاستطلاع 60 ثانية، فلديك نقطة عينة واحدة فقط في تلك النافذة — استخدم على الأقل 4 نقاط استطلاع لكل نافذة تنبيه.
  • إعادة ضبط العداد عند إعادة تشغيل الحاوي: تتعامل rate() مع عمليات إعادة الضبط بشكل صحيح؛ delta() لا تفعل ذلك. استخدم rate() أو increase() للعدادات عبر عمليات إعادة التشغيل.
  • انفجار عدد المقاييس: إضافة تسمية عالية الكثافة (معرف المستخدم، معرف الطلب) لعداد ينشئ ملايين السلاسل وفي نهاية المطاف يُطيح بـ Prometheus. أبقِ التسميات محدودة.
  • انجراف الساعة بين العقد: المقاييس من عقد ذات انجراف NTP تظهر خارج الترتيب ويمكن أن تجعل rate() تُرجع قيماً سالبة. تحقق من node_timex_sync_status.
# التحقق من صحة استطلاع Prometheus لأهداف node-exporter curl -s http://localhost:9090/api/v1/targets | \ jq '.data.activeTargets[] | select(.health != "up") | {job: .labels.job, instance: .labels.instance, err: .lastError}' # إحصاءات TSDB لـ Prometheus (تحليل الكثافة) curl -s http://localhost:9090/api/v1/status/tsdb | jq '.data.headStats'

مع إعداد وفهم هذه الإشارات، لديك أساس القياس الذي يعتمد عليه كل درس لاحق في هذا البرنامج التعليمي — مقاييس هدف HPA، توصيات VPA، مشغلات تحجيم مجموعة العقد، وخطوط أساس مراجعة السعة كلها ترجع إلى أرقام الاستخدام والإشباع التي تجمعها هنا.