SSD Nodes Learn 🎉 VPS من $4.99/شهر
الأدلة Matt Connorبقلم Matt Connor

ما هو CPU steal وكيف تكشف جاراً مزعجاً على VPS؟

افهم رسالة CPU steal، واقرأ عمود st في vmstat، وميّز بين جار مزعج يشاركك المضيف وبين حمل زائد ناتج من خادمك.

ما الذي يقيسه وقت CPU steal فعلياً

وقت CPU steal هو نسبة الوقت الذي كان فيه CPU الافتراضي جاهزاً للتنفيذ، من دون انتظار أي مورد، بينما منح الـhypervisor النواة الفعلية لضيف افتراضي آخر. كان العمل في قائمة الانتظار. وكانت النواة مشغولة في مكان آخر. يحسب Linux هذه الدورات بشكل منفصل ويعرضها كـ st، وهذا يتيح لك التمييز بين «الخادم مشغول» و«الخادم ينتظر دوره».

هذا الفرق هو السبب الكامل لوجود هذا العداد. يُعرض الوقت الذي تقضيه عملياتك على CPU كـ us (user) أو sy (system). ويُعرض الوقت الذي تقضيه المهمة محجوبة بانتظار التخزين كـ wa (I/O wait). أما vCPU (CPU افتراضي) القابل للتنفيذ، الموجود في قائمة التشغيل، والذي لا توجد لديه عمليات I/O معلقة، لكنه لا يزال لا ينفذ، فيُعرض كـ st. لا يمكن لأي شيء داخل خادمك إزالة هذه الحالة، لأن قرار الجدولة يُتخذ في طبقة أدنى منك، على المضيف.

ينتج ذلك مباشرة عن كيفية مشاركة VPS واحد بين عدة ضيوف على جهاز فعلي واحد. والسبب المعتاد هو جار: ضيف آخر على العقدة نفسها يستهلك CPU بكثافة، لذلك يقسم المضيف الأنوية بينكما. وهناك سبب ثانٍ غالباً ما يُغفل. يحدد العديد من المزودين vCPU مشتركاً عند جزء من نواة فعلية، وفي عدة hypervisors يُحتسب هذا الحد المفروض كـ steal داخل الضيف. لذلك تخبرك قراءة st المرتفعة بأن النواة لم تُمنح لك. لكنها لا تخبرك دائماً بمن حصل عليها.

مصدر قيمة steal

لا يستطيع kernel قياس steal بنفسه، لأنه لا يرى المضيف. يخبره hypervisor بهذه القيمة. في KVM، يكتب المضيف عدّاداً مستقلاً لكل vCPU في صفحة مشتركة مع guest، ثم يجمع guest هذه القيمة عندما يكون kernel مبنياً مع CONFIG_PARAVIRT_TIME_ACCOUNTING، وهو متاح في كل kernel توزّعه التوزيعات. يبلّغ Xen عن القيمة نفسها من خلال منطقة runstate. تصل القيمة الإجمالية إلى userspace في موضع واحد فقط:

head -1 /proc/stat

يحمل سطر cpu عشرة عدّادات بوحدة نبضات USER_HZ منذ الإقلاع، بالترتيب التالي: user، وnice، وsystem، وidle، وiowait، وirq، وsoftirq، وsteal، وguest، وguest_nice. قيمة steal هي القيمة الثامنة بعد اسم الحقل. تقرأ كل الأدوات التالية، وهي vmstat وtop وmpstat وأي Prometheus exporter، الحقل نفسه وتحول عينتين إلى نسبة مئوية.

هناك نتيجة واحدة أهم من غيرها. إذا لم يصدّر hypervisor العدّاد، فستبقى القيمة صفراً إلى الأبد، وستبلغ كل أداة مبنية عليها عن 0.0 هادئ بينما يكون المضيف محمّلاً بشدة. يصدّر KVM وXen هذه القيمة. أما guests على VMware وHyper-V فعادةً ما يبلّغون عن صفر ثابت. تحقّق من المنصة قبل أن تثق بقيمة الصفر:

systemd-detect-virt

يطبع هذا الأمر اسم المنصة، مثل kvm أو xen أو vmware أو microsoft، ويطبع none عند التشغيل على bare metal. داخل container، يبلّغ عن runtime بدلاً من ذلك، مثل lxc أو docker أو podman، وهذا يوضح حالة container لا حالة الجهاز الذي يعمل تحته. على kvm، يكون الصفر دليلاً حقيقياً على أن المضيف يعامل جهازك جيداً. أما على منصة لا تملأ هذا الحقل أبداً، فلا يقدم الصفر أي دليل، ويجب تقييم التنافس على الموارد عبر قياس زمن تنفيذ العمل الفعلي.

كيف أتحقق من وقت سرقة CPU على VPS؟

يأتي vmstat من حزمة procps. وهي موجودة في معظم صور VPS الخاصة بـUbuntu وDebian، لكنها مفقودة في بعض صور الحاويات المصغّرة. لذلك ثبّتها قبل الاعتماد عليها.

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

يطبع vmstat --version سطراً مثل vmstat from procps-ng 4.0.4. إذا ظهر هذا السطر، فهذا يعني أن الأداة مثبّتة وأنك تقرأ عدادات حقيقية من kernel. بعد ذلك يأخذ vmstat 1 5 عينة واحدة كل ثانية، لمدة خمس مرات.

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

ابحث عن عمود st داخل كتلة cpu الموجودة على اليمين. تطبع الإصدارات الحالية من procps-ng عمود gu بعده لوقت ضيف KVM، لذلك يصبح st ثاني عمود من اليمين بدلاً من كونه العمود الأخير. اقرأ العمود بالاعتماد على اسم ترويسة العمود، لأن موضعه تغيّر بين الإصدارات.

تساعد عادتان في إبقاء القراءة دقيقة. السطر الأول من البيانات هو المتوسط منذ الإقلاع، لذلك تجاهله واقرأ الأسطر التي تليه. كما أن عينة واحدة لا تكفي للقياس، لأن وقت السرقة يصل على دفعات. شغّل vmstat 1 60 وراقب دقيقة كاملة قبل استخلاص نتيجة.

يعرض top الرقم نفسه في سطر الملخص %Cpu(s)، داخل الحقل المعلَّم بـst:

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

للحصول على تفاصيل كل نواة، أضف sysstat:

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

يطبع mpstat صفاً واحداً لكل CPU مع عمود %steal، ويبيّن ما إذا كانت المشكلة تؤثر في كل vCPU أو في واحد منها فقط. وللاحتفاظ بالسجل الذي يحتاج إليه طلب الدعم، خزّن العينات بدلاً من قراءتها من الشاشة:

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

شغّل ذلك من cron خلال الساعات التي تشتبه بحدوث المشكلة فيها. عندها يصبح الملف الفرق بين إخبار المزوّد بأن الأداء «كان بطيئاً الليلة الماضية» وعرض الدقائق العشر المحددة له.

ماذا تعني قيم steal؟

  • قيمة 0.0 مستقرة. هذا مؤشر صحي، أو أن المنصة لا تعرض steal على الإطلاق. أكّد ذلك باستخدام systemd-detect-virt قبل أن تستنتج أن كل شيء سليم.
  • ارتفاعات إلى بضعة بالمئة تستمر ثوانٍ. هذا طبيعي على أي عقدة مشتركة. قد يبدأ جارٌ عملية بناء، أو قد يشغّل المضيف نسخاً احتياطية.
  • قيمة مستمرة بين 1 و5 بالمئة على خطة مشتركة. هذا متوقع. تعكس التكلفة استخدام CPU مشتركاً.
  • قيمة مستمرة بين 5 و10 بالمئة. هذا تباطؤ يمكن قياسه. ابدأ بتسجيل الأدلة، وقارن الساعات نفسها على مدار عدة أيام.
  • أكثر من 10 بالمئة لعدة ساعات متواصلة. العقدة محمّلة بأكثر من قدرتها بالنسبة إلى عبء عملك. هذا هو المستوى الذي يبرر فتح تذكرة دعم أو الانتقال إلى عقدة أخرى.

تعامل مع هذه النطاقات كدليل للقراءة، لا كمواصفة، لأن أي مزود لا ينشر ضماناً لقيمة steal في الخطط المشتركة. قيّمها في ضوء ما تشغّله. يمكن لمهمة دفعة ليلية أن تتحمل steal بنسبة 15 بالمئة من دون أن يلاحظ أحد ذلك. أما الخدمة الحساسة لزمن الاستجابة فتُظهره في p99 قبل وقت طويل من ظهور متوسط مقلق، ولذلك ينبغي تشغيل أعباء العمل الحساسة لزمن الاستجابة مثل روبوتات التداول على أنوية مخصصة.

ما تكلفة وقت السرقة عليك؟

الحساب مختصر. إذا استُهلك جزء s من وقت CPU لديك، فإن المهمة التي تحتاج إلى مقدار ثابت من CPU تستغرق على مدار الساعة مدة أطول بمقدار 1 / (1 - s) مرة. بالنسبة إلى مهمة تحتاج إلى 60 ثانية من CPU:

ChartWall clock time for a job needing 60 seconds of CPU
The data behind this chart
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

عند 3 بالمئة، وهي قراءة عادية في خطة مشتركة، تستغرق المهمة 61.9 ثانية بدلاً من 60.0. لا يفتح أحد تذكرة بسبب ذلك. عند 8 بالمئة، تستغرق 65.2 ثانية. وعند 40 بالمئة، تحتاج المهمة نفسها إلى 100.0 ثانية، ويبدأ طابور كان يُفرَّغ سابقاً في الازدياد بدلاً من ذلك.

هذه قيم محسوبة وليست قياسات. يفترض النموذج وجود thread واحد قابل للتشغيل، وتوزيع وقت السرقة بالتساوي على الفترة. غالباً ما تبدو الخدمات الفعلية أسوأ من المنحنى، لأن شريحة مسروقة قد تقع في منتصف طلب، ثم يتحمل كل ما ينتظر ذلك الطلب التأخير نفسه مرة أخرى. للحصول على قيمة خاصة بك بدلاً من استخدام صيغة عامة، نفّذ اختبار أداء لـVPS خلال ساعة هادئة ثم خلال ساعة مزدحمة، وسجّل st لكلتا الفترتين.

هل هي Steal أم شيء آخر؟

من السهل الخلط بين Steal والأعراض الأخرى. اقرأ العدادات معاً، في سطر vmstat نفسه.

  • ارتفاع st مع بقاء r وus منخفضين: لا يمنحك المضيف وقت المعالج. هذه هي حالة Steal.
  • ارتفاع r كثيراً فوق عدد vCPU لديك، مع ارتفاع us واقتراب st من الصفر: أنت تشغّل أعمالاً أكثر مما تستطيع معالجاتك الخاصة استيعابه. قارن r بمخرجات nproc. هذه زيادة في تحميل مواردك أنت، وليست بسبب جار.
  • ارتفاع wa مع اقتراب st من الصفر: المهام محجوبة بانتظار التخزين. هذه مشكلة مختلفة ولها إصلاح مختلف.
  • ارتفاع متوسط التحميل مع انخفاض كل من st وus: يحسب مؤشر التحميل أيضاً المهام غير القابلة للمقاطعة، لذلك يشير هذا عادةً إلى جهاز عالق أو عملية mount شبكية معلّقة، وليس إلى المعالج.

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

لماذا لا تُظهر الحاوية وقت السرقة

وقت السرقة خاص بالآلة الافتراضية، وليس بالحاوية التي تعمل داخلها. تشارك حاوية Docker على VPS الخاص بك في /proc الخاص بالمضيف، لذلك تكون قيمة st المقروءة داخلها هي وقت السرقة في VPS، وهذا هو المطلوب. تختلف الافتراضية المعتمدة على الحاويات والمباعة بصفتها VPS. عند استخدام lxcfs، تُنشأ قيمة /proc/stat داخل الحاوية من محاسبة cgroup، ويكون وقت السرقة صفراً بحكم التصميم. يمكن لمكدس المراقبة الذي يجمع البيانات من داخل الحاوية فقط أن يعرض صفراً ثابتاً وهادئاً، بينما يعاني الجهاز الفعلي في الأسفل من نقص الموارد.

داخل الحاوية، العداد الذي يحمل المعنى نفسه هو خنق حصة CPU. في cgroup v2:

cat /sys/fs/cgroup/cpu.stat

يحصي nr_throttled فترات الإنفاذ التي بلغت فيها المجموعة حصتها من CPU، بينما يجمع throttled_usec إجمالي الوقت الذي بقيت فيه متوقفة. تشير زيادة nr_throttled إلى أن العملية كانت قابلة للتشغيل لكنها لم تكن تعمل، وهو الإحساس نفسه الذي يسببه وقت السرقة، لكن السبب هنا حدّ ضبطته بنفسك. تحقّق من حدودك أولاً قبل إلقاء اللوم على المضيف، خصوصاً إذا كنت تشغّل خدماتك في Docker على VPS مع تحديد حدود CPU في ملف compose. تضيف الافتراضية المتداخلة موضعاً آخر لاختفاء الوقت، لأن آلة افتراضية داخل VPS الخاص بك تتحمل وقت السرقة الخاص بك، إضافة إلى تأخير الجدولة الخاص بها. ضع ذلك في الاعتبار إذا كنت تشغّل افتراضية متداخلة على VPS.

ما الذي تفعله حيال steal المستمر

لا يمكن لأي إعداد داخل guest إصلاح steal، لأن المجدول الذي يتخذ القرار يعمل خارج guest. هناك أربعة إجراءات فعلية.

اجمع الأدلة أولاً. سجّل الطوابع الزمنية بتوقيت UTC، ومدة كل حالة، وعدد مرات تكرارها، وما إذا كان mpstat يوضح تأثر vCPU واحد أو جميع vCPU. إن تسجيل العينات لمدة أسبوع أفضل من لقطة شاشة.

افتح تذكرة بهذه البيانات. اطرح سؤالين مباشرين: هل هذه العقدة تعاني من زيادة في تخصيص الموارد خلال هذه الفترات؟ وهل يمكن نقل instance الخاصة بي؟ أرفق ناتج vmstat والأوقات الدقيقة. يتعامل مزودو الخدمة مع فترة زمنية يمكن إعادة إنتاجها، أما التذكرة التي تقول فقط إن الخادم بطيء فستتلقى رداً يطلب تحديد هذه الفترة. ويُعد مقدار العمل الذي يمكنك إسناده إلى المزود أحد الفروق العملية بين VPS مُدار وVPS غير مُدار.

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

ادفع مقابل التخلص من التنافس على الموارد. تحجز خطة vCPU مخصصة أنوية فعلية لـinstance الخاصة بك، لذلك يبقى العداد عند الصفر. تكلف هذه الخطة مبلغاً أكبر كل شهر، لكنها الخيار الصريح لحِمل عمل لا يتحمل التباين. إذا لم يكن ذلك كافياً، أو كنت تريد أيضاً حجز عرض نطاق الذاكرة لك وحدك، فالخطوة التالية هي خادم مخصص بدلاً من VPS.

أثناء انتظارك لأي من هذه الإجراءات، قلّل أثر steal. شغّل عدداً من worker threads أقل من عدد vCPU المتاح، لأن threads التي لا تحصل على نواة لا تضيف إلا تبديلات السياق. انقل أعمال المعالجة الدفعية إلى الساعات التي تكون فيها العقدة هادئة، وفقاً لما يوضحه سجلك الآن. ثم أعد القياس باستخدام الأمر نفسه خلال الساعات نفسها، حتى تتمكن من تحديد ما إذا كان التغيير قد نجح بدلاً من التخمين.

FAQ

ما قيمة وقت سرقة وحدة المعالجة المركزية الطبيعية على VPS؟

في الخطة المشتركة، تكون الارتفاعات القصيرة والقيمة المستمرة التي تقل عن نحو 5 بالمئة أمراً اعتيادياً، لأن وحدة المعالجة المركزية المشتركة تعني أن المضيف يوزّع الأنوية الفعلية بين الضيوف. أما استمرار القيمة عند خانتين رقميتين طوال ساعات فليس اعتيادياً، ويستحق فتح تذكرة دعم. في خطة vCPU مخصصة، تكون القراءة المتوقعة هي 0.0، ولذلك فإن ظهور أي قيمة أخرى يمثل عطلاً يجب الإبلاغ عنه. قيّم الرقم مقابل حمل العمل لديك: فوظيفة معالجة دفعية تعمل طوال الليل قد تتحمل وقت السرقة، بينما لا يستطيع API حساس لزمن الاستجابة تحمله.

هل ستؤدي الخطة الأكبر إلى حل ارتفاع وقت السرقة؟

ليس بالضرورة. فزيادة عدد vCPUs على العقدة المشتركة نفسها تعني وجود عدد أكبر من وحدات المعالجة الافتراضية التي تتنافس على الأنوية الفعلية المزدحمة نفسها، وقد تبقى النسبة كما هي تماماً. ما يزيل وقت السرقة هو تخصيص وحدة معالجة مركزية مخصصة، أو النقل إلى عقدة أقل حملاً. فالحصة الأكبر من جهاز مزدحم تظل حصة من جهاز مزدحم.

لماذا يعرض VPS لدي وقت سرقة بقيمة 0 رغم أنه بطيء بوضوح؟

هناك سببان شائعان. قد لا يصدّر برنامج مراقبة الأجهزة الافتراضية العداد أصلاً، وهذا شائع في منصات VMware وHyper-V، ولذلك يبقى الحقل عند الصفر مهما فعل المضيف. شغّل systemd-detect-virt لمعرفة المنصة التي تستخدمها. وإلا فقد يكون الاختناق في موضع آخر: افحص wa بحثاً عن انتظار التخزين، وقارن r مع nproc لاكتشاف الحمل الزائد لديك، واقرأ /sys/fs/cgroup/cpu.stat داخل الحاويات للتحقق من تقييد الحصة.

هل يمكنني تقليل وقت السرقة من داخل خادمي؟

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