← شروع آموزش

WIUNIX ACADEMY

تشخیص کندی I/O در لینوکس با iostat و PSI

صفحهٔ 2 از 3؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راه‌حل‌های همون محیط رو ببینی.

Ubuntu 26.04 LTSبررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه می‌مونن و به سرور یا لینک اشتراک‌گذاری فرستاده نمی‌شن. قبل از اجرا، DNS، گواهی‌ها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.

اگر آی‌پی، دامنه یا پورت‌های نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.

تنظیم مقادیر برای محیط من4 مقدار قابل‌تغییر
06

قدم بعدی

انتظار I/O رو با کمبود حافظه اشتباه نگیریم

در همون بازهٔ کندی، با vmstat تصویر حافظه و پردازش‌ها رو هم می‌گیریم. ستون‌های نرخ و CPU در ردیف اول میانگین از زمان بوت هستن؛ برای مقایسهٔ بازهٔ جاری ردیف‌های بعدی رو بخون. وضعیت پردازش و حافظه در همهٔ ردیف‌ها لحظه‌ایه. پردازش‌های blocked، ورود و خروج swap و ستون‌های CPU رو با هم ببین. ستون wa زمان بیکاری CPU در حضور I/O معوقه است، نه درصدی از عمر برنامه که صرف انتظار دیسک شده.

ممکنه یک برنامه منتظر I/O باشه ولی کارهای دیگه CPU رو مشغول نگه دارن و wa پایین بمونه. از طرف دیگه، پس‌گرفتن حافظه و swap هم می‌تونه ترافیک دیسک بسازه، بدون اینکه خواندن پایگاه داده بیشتر شده باشه. این نشونه‌ها کمک می‌کنن علت محتمل رو انتخاب کنیم؛ مجوز تغییر swap، پاک‌کردن cache یا دست‌کاری writeback نیستن.

bash

ترمینال مجاز روی همان میزبان لینوکس درگیر

date -u +%FT%TZ
LC_ALL=C vmstat 1 6
از کجا بفهمم درست انجام شده؟

پنج ردیف بازه‌ایِ بعد از خلاصه رو با فشار و آمار دستگاه مقایسه می‌کنیم؛ paging با I/O برنامه یکی فرض نمی‌شه.

07

قدم بعدی

کدوم پردازش با این بار هم‌زمانه؟

حالا سراغ پردازش‌هایی می‌ریم که هم‌زمان با کندی، خواندن یا نوشتن زیادی دارن. pidstat کمک می‌کنه این نامزدها رو پیدا کنیم. خروجی فقط نام پردازش رو نشون می‌ده، نه آرگومان‌هایی که ممکنه دادهٔ خصوصی داشته باشن. زیادبودن نوشتن یک پردازش هنوز ثابت نمی‌کنه همهٔ کارِ دیسک در همان لحظه از طرف اونه؛ بخشی از نوشتن ممکنه در بافر مونده باشه و بعداً به دیسک برسه، یا چند پردازش از یک فایل‌سیستم استفاده کنن.

صفر یا خالی‌بودن iodelay وقتی حسابداری تأخیر پردازش‌ها فعال نیست نتیجهٔ قطعی نمی‌ده. نیازهای کرنل در FAQ پروژهٔ sysstat توضیح داده شده. برای تکمیل یک ستون، وسط حادثه delay accounting رو فعال نکن و دسترسی procfs رو بازتر نکن؛ محدودیت دید رو با مسئول میزبان روشن و در گزارش نگه دار.

bash

ترمینال مجاز روی همان میزبان لینوکس درگیر

date -u +%FT%TZ
LC_ALL=C pidstat -d -p ALL 1 5
از کجا بفهمم درست انجام شده؟

فهرست محدودی از PIDهای نامزد، در حد دسترسی فعلی داریم؛ نبود حسابداری و محدودیت انتساب نوشتن بافرشده همچنان مشخصه.

08

قدم بعدی

اگر سرویس مشخصه، محدودهٔ خودش رو پیدا کنیم

برای example نام واقعی سرویس systemd رو بدون پسوند .service وارد کن. قبل از انتخاب مسیر cgroup، هویت سرویس و ControlGroup رو می‌بینیم. این بخش اختیاری به cgroup v2 و دید خود میزبان نیاز داره؛ گروهی نمی‌سازیم و پردازشی رو جابه‌جا نمی‌کنیم. داخل کانتینر ممکنه مسیر واقعی میزبان دیده نشه.

محل واقعی mount از نوع cgroup2 رو با ControlGroup برگشتی کنار هم بگذار و مسیر کاملِ موجود رو در /sys/fs/cgroup/system.slice/example.service وارد کن. مقدار نمونه نام سرویس کشف‌شده نیست. اگر unit پیدا نشد یا ControlGroup خالی بود، همین بخش رو متوقف کن؛ مسیر حدسی جای نتیجهٔ مشاهده رو نمی‌گیره.

bash

ترمینال مجاز روی همان میزبان لینوکس درگیر

systemctl show 'example.service' -p Id -p LoadState -p ActiveState -p MainPID -p ControlGroup
findmnt -t cgroup2 -o TARGET,FSTYPE,OPTIONS
از کجا بفهمم درست انجام شده؟

نام سرویس و پوشهٔ واقعی cgroup v2 مشخص شدن. اگر این میزبان یا دسترسی فعلی اجازهٔ دیدن اون محدوده رو نمی‌ده، همین بخش اختیاری رو ادامه نمی‌دیم و دلیلش رو ثبت می‌کنیم.

09

قدم بعدی

فشار سرویس و محدودیت‌هاش رو مقایسه کنیم

حالا پوشهٔ کشف‌شدهٔ سرویس رو دو بار می‌خونیم. io.stat بایت و عملیات رو به تفکیک major:minor می‌شماره؛ تغییر هر دستگاه رو در همین فاصله با نقشهٔ lsblk تطبیق بده. io.max سقف تنظیم‌شده رو نشون می‌ده. داشتن سقف ثابت نمی‌کنه سرویس بهش رسیده؛ نبود سقف در این پوشه هم محدودیت والد یا ارائه‌دهندهٔ دیسک رو رد نمی‌کنه.

ممکنه خود میزبان راحت باشه ولی سرویس در محدودهٔ خودش معطل بمونه. اگر لازم بود سیاست والد رو با مسئول سرویس بررسی کن؛ برای بهترشدن عددها io.max، io.weight یا واگذاری controller رو تغییر نمی‌دیم. همهٔ کرنل‌ها و آرایش‌های cgroup همهٔ فایل‌ها رو ندارن؛ نبود رابط رو صفر حساب نکن.

bash

ترمینال مجاز روی همان میزبان لینوکس درگیر

(
set -eu
cg='/sys/fs/cgroup/system.slice/example.service'
test -d "$cg"
test "$(findmnt -n -o FSTYPE --target "$cg")" = cgroup2
for sample in 1 2; do
  date -u +%FT%TZ
  for name in io.pressure io.stat io.max memory.pressure; do
    printf '\n%s\n' "$name"
    if test -r "$cg/$name"; then cat "$cg/$name"; else printf 'unavailable or unreadable\n' >&2; fi
  done
  if test "$sample" = 1; then sleep 5; fi
done
)
از کجا بفهمم درست انجام شده؟

برای این سرویس دو نمونهٔ زمان‌دار داریم تا تغییر آمار I/O، فشار و سقف قابل‌مشاهده رو مقایسه کنیم. اگر فایل لازم دیده نمی‌شه یا محدودیت از والد یا ارائه‌دهنده میاد، هنوز باید همون بخش رو با مسئولش بررسی کنیم.

حالا بر اساس شواهد تصمیم بگیریم

اگر تأخیر برنامه، فشار I/O و صف یا await دستگاه با بار قابل‌مقایسه هم‌زمان بالا می‌رن، مسیر ذخیره‌سازی و محدودیت یا خطای پشتش رو بررسی کن. اگر فشار در یک سرویس جمع شده ولی دستگاه‌های میزبان مشکلی نشون نمی‌دن، سلسله‌مراتب cgroup و الگوی کار همون سرویس مهم‌تره. اگر اول فشار حافظه و swap بالا رفته، قبل از خرید دیسک سریع‌تر سراغ رشد حافظهٔ مصرفی و سقف حافظه برو.

اگر درخواست کند شده ولی این مشاهده‌ها عادی موندن، همین نتیجهٔ منفی رو نگه دار و قفل‌های برنامه، وابستگی شبکه‌ای یا زمان‌بندی CPU رو دنبال کن. نمونهٔ کوتاه ممکنه جهش رو از دست بده؛ یک بازهٔ محدود رو دقیقاً موقع خطا تکرار کن، نه اینکه آرام‌بودن زمان نامرتبط رو موفقیت حساب کنی.

در هر نوبت فقط یک اقدامِ مصوب انتخاب کن؛ مثلاً هم‌زمانی یک کار batch قابل‌تکرار رو از زمان‌بند خودش کمتر کن یا ساعتش رو از اوج مصرف جلوتر یا عقب‌تر ببر. مقدار قبلی تنظیم و روش رسیدگی به کارهای عقب‌افتاده رو نگه دار. کندکردن، توقف یا تکرار کار می‌تونه زمان پایان و تازگی داده رو عوض کنه؛ این تصمیمِ برنامه است، نه تعمیر عمومی با یک فرمان شل.

وقتی عددها با هم جور نیستن

از بررسی متناسب پایین استفاده کن و خطاها رو نگه دار. برای به‌دست‌آوردن یک اندازه‌گیری، روی میزبان عملیاتی بارساز نصب نمی‌کنیم، cache رو پاک نمی‌کنیم، زمان‌بند I/O یا حفاظت سیستم رو عوض نمی‌کنیم و سیستم رو ری‌استارت نمی‌کنیم.

PSI پیدا نمی‌شه یا خواندنی نیست

کرنل و رابطی رو که واقعاً می‌بینی بررسی کن. mount کانتینر، تنظیم کرنل یا سیاست زمان بوت ممکنه PSI رو غیرفعال یا پنهان کرده باشه. این بخش رو در دسترس‌نبوده ثبت کن و با مسئول میزبان هماهنگ شو؛ فشار رو صفر فرض نکن.

bash
uname -r
ls -ld /proc/pressure
ls -l /proc/pressure/io /proc/pressure/memory
دستگاه مورد انتظار در iostat نیست

دوباره منبع فایل‌سیستم و درخت دستگاه‌ها رو ببین. فایل‌سیستم شبکه‌ای، overlay یا فضای نام متفاوت ممکنه به دیسکی که حدس زدی وصل نباشه؛ گاهی خود آمار کرنل هم در دسترس نیست. نبود ردیف، سلامت دستگاه رو ثابت نمی‌کنه.

bash
findmnt --target '/var/lib' -o TARGET,SOURCE,FSTYPE
lsblk -o NAME,KNAME,MAJ:MIN,TYPE,MOUNTPOINTS
head -n 12 /proc/diskstats
pidstat کار زیادی نشون نمی‌ده

ممکنه پردازش تمام شده باشه، مجوز دیدن اطلاعاتش رو نداشته باشی یا حسابداری در دسترس نباشه؛ I/O بافرشده یا شبکه‌ای هم الزاماً با بازهٔ دستگاه یکی نیست. PID نامزد رو همون لحظه دوباره شناسایی کن، چون PID دوباره استفاده می‌شه. comm آرگومان خصوصی رو چاپ نمی‌کنه.

bash
ps -p '1234' -o pid=,ppid=,user=,comm=,lstart=
cat '/proc/1234/cgroup'
پوشهٔ cgroup سرویس عوض شده یا نیست

با توقف یا راه‌اندازی دوبارهٔ پردازش‌ها، محدودهٔ سرویس هم ممکنه عوض بشه. ControlGroup و mount واقعی cgroup2 رو دوباره پیدا کن و بعد مقدار نمونه رو اصلاح کن. برای موفق‌شدن خواندن، در cgroupfs پوشه نساز.

bash
systemctl show 'example.service' -p LoadState -p ActiveState -p MainPID -p ControlGroup
findmnt -t cgroup2 -o TARGET,FSTYPE
همهٔ آموزش‌های آکادمی ↗