پرش به محتویات

۱۲. کارایی و منابع سیستم

روش پایه: برای هر منبع (CPU، حافظه، دیسک، شبکه) سه چیز را بپرسید — Utilization (چقدر مشغول است)، Saturation (آیا صف دارد/کسی منتظر است)، Errors (خطا دارد؟). این روش (USE) از حدس‌زدن جلوگیری می‌کند. قبل از restart، شواهد را ذخیره کنید.

راهنمای سریع

فرمان کاربرد ریسک
uptime / top / vmstat 1 5 بار و وضعیت کلی بدون تغییر
mpstat -P ALL 1 5 / pidstat 1 5 CPU به تفکیک هسته/پردازش بدون تغییر
free -h / /proc/meminfo / swapon --show حافظه بدون تغییر
iostat -xz 1 5 / iotop -oPa دیسک بدون تغییر
sar -u/-r/-d/-n DEV سابقهٔ منابع بدون تغییر
cat /proc/pressure/* فشار منابع (PSI) بدون تغییر
strace -c -p PID / perf top ردیابی عمیق تغییر (پردازش را کند می‌کند)
sysctl -w / تغییر limit تنظیم هسته تغییر
echo 3 > /proc/sys/vm/drop_caches تخلیهٔ کش تغییر (راه‌حل نیست)

تصویر ۶۰ ثانیه‌ای

uptime
dmesg -T | tail
vmstat 1 5
mpstat -P ALL 1 3
pidstat 1 3
iostat -xz 1 3
free -h
sar -n DEV 1 3
sar -n TCP,ETCP 1 3
top -bn1 | head -15

CPU و Load

uptime
nproc
top
mpstat -P ALL 1 5
pidstat 1 5
ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head
top -H -p PID            # نخ‌های یک پردازش

mpstat و pidstat معمولاً از بسته sysstat هستند. Load average تعداد کارهای در حال اجرا یا منتظر منابع (شامل I/O) را منعکس می‌کند؛ آن را نسبت به تعداد CPUها و روند زمانی (۱، ۵، ۱۵ دقیقه) تفسیر کنید.

الگو معنی
load بالا، CPU us/sy بالا CPU اشباع
load بالا، CPU بیکار، wa بالا منتظر دیسک/NFS (پردازش‌های D)
st (steal) بالا در VM میزبان مجازی منابع را از ما می‌گیرد؛ به ارائه‌دهنده/host بگویید
یک هسته ۱۰۰٪، بقیه بیکار برنامه تک‌نخی؛ افزودن هسته کمک نمی‌کند
sy (system) بالا تعداد زیاد syscall / interrupt / context switch

حافظه

free -h
vmstat 1 5
ps -eo pid,comm,rss,%mem --sort=-rss | head
grep -E 'MemTotal|MemAvailable|SwapTotal|SwapFree' /proc/meminfo
swapon --show
sudo slabtop -o | head -15         # مصرف حافظهٔ کرنل

در لینوکس حافظه آزاد کم به‌تنهایی نشانه مشکل نیست؛ cache/buffer قابل استفاده مجدد است. به available، swap، فشار حافظه و OOM توجه کنید. نشانهٔ مشکل واقعی: available نزدیک صفر + si/so (swap in/out) پیوسته غیرصفر در vmstat + پیام OOM.

drop_caches راه‌حل نیست

echo 3 > /proc/sys/vm/drop_caches فقط کش را خالی و کارایی را موقتاً بدتر می‌کند؛ مشکل واقعی (نشت حافظه یا کمبود) را حل نمی‌کند.

دیسک و I/O

iostat -xz 1 5
sudo iotop -oPa
df -hT
du -xhd1 /var 2>/dev/null | sort -h
sudo journalctl -k | grep -Ei 'oom|I/O error|reset|timeout'

iostat و iotop به بسته‌های مربوطه نیاز دارند. ستون‌های مهم iostat -x: r_await/w_await (تأخیر ms)، aqu-sz (طول صف)، %util. درصد utilization یا latency باید با نوع ذخیره‌ساز، workload و baseline مقایسه شود: %util نزدیک ۱۰۰ روی دیسک مکانیکی = اشباع؛ روی NVMe/SSD موازی، %util به‌تنهایی معیار خوبی نیست، به await و aqu-sz نگاه کنید.

فشار منابع (PSI)

هسته‌های ۴.۲۰+ مستقیم می‌گویند «چه مدت کارها منتظر منبع بودند»:

cat /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io
# some avg10=0.00 avg60=0.00 ...   ← avg10 بالای چند درصد = تأخیر محسوس

سابقه با sar

sudo systemctl enable --now sysstat       # Debian: در /etc/default/sysstat مقدار ENABLED="true"
sar -u                      # CPU امروز
sar -r                      # حافظه
sar -d -p                   # دیسک
sar -n DEV                  # شبکه
sar -q                      # load / صف اجرا
sar -u -f /var/log/sysstat/sa29        # روز ۲۹ ماه (RHEL: /var/log/sa/sa29)

بدون جمع‌آوری سابقه، به سؤال «ساعت ۳ شب چه شد؟» نمی‌توان جواب داد؛ sysstat را همه‌جا فعال کنید.

محدودیت و OOM

systemctl show myservice -p MemoryMax -p CPUQuota -p LimitNOFILE -p TasksMax
journalctl -k | grep -iE 'out of memory|killed process'
dmesg -T | grep -iE 'out of memory|oom-kill'
systemd-cgtop
ulimit -n                       # فایل باز مجاز برای این شِل
cat /proc/PID/limits | grep -i 'open files'
ls /proc/PID/fd | wc -l         # فایل باز فعلی
sysctl vm.swappiness fs.file-max

در محیط‌های cgroup/container، محدودیت سرویس ممکن است با ظرفیت کلی سرور متفاوت باشد (OOM در cgroup بدون پر شدن RAM کل). پیش از افزایش RAM یا restart، شواهد را جمع‌آوری کنید. خطای Too many open files: LimitNOFILE سرویس را در unit/drop-in افزایش دهید (سرویس‌ها)، نه فقط ulimit در شِل.

پردازش‌های گیرکرده در I/O (حالت D)

وقتی load بالاست ولی CPU بیکار است، پردازش‌های D (انتظار غیرقابل‌قطع) را با محل انتظارشان ببینید:

ps -eo state,pid,wchan:32,comm | awk '$1=="D"'
cat /proc/PID/stack 2>/dev/null          # نیاز به root؛ محل انتظار در هسته
sudo journalctl -k --since '-10min' | grep -Ei 'hung task|blocked for more than'

اگر چند پردازش مدت طولانی روی NFS، دیسک یا multipath در حالت D هستند، kill -9 اثر ندارد؛ باید منبع ذخیره‌سازی را درست کنید.

حافظه (عمیق‌تر)

# چه پردازش‌هایی swap مصرف کرده‌اند؟
for f in /proc/[0-9]*/status; do awk '/^Name:/{n=$2} /^VmSwap:/{s=$2} END{if(s>0)print s" kB",n}' "$f" 2>/dev/null; done | sort -nr | head
grep -E 'Dirty|Writeback:' /proc/meminfo     # داده‌ای که هنوز روی دیسک نوشته نشده
  • Dirty بزرگ و wa بالا ← نوشتن سنگین و دیسک کند؛ دیسک و I/O را ببینید.
  • swap پر ولی si/so در vmstat صفر: پردازش‌های بی‌کار به swap رفته‌اند و معمولاً مشکل نیست؛ تعیین‌کننده swap in/out پیوسته است.

OOM داخل cgroup (سرویس systemd)

سرویس می‌تواند با MemoryMax کشته شود، در حالی که RAM کل سرور خالی است (فقط روی cgroup v2؛ مسیرها را روی سیستم خودتان بررسی کنید):

systemctl show myapp.service -p MemoryCurrent -p MemoryMax
cat /sys/fs/cgroup/system.slice/myapp.service/memory.events   # شمارندهٔ oom و oom_kill
cat /sys/fs/cgroup/system.slice/myapp.service/memory.pressure

oom_kill غیرصفر در memory.events یعنی سقف حافظهٔ سرویس رد شده است؛ نشت حافظه را بررسی کنید و بعد سقف را تغییر دهید (drop-in).

تفسیر iostat

الگو در iostat -xz 1 معنی اقدام
await بالا، aqu-sz بزرگ، %util ~۱۰۰ روی HDD دیسک اشباع پردازش مسبب را با pidstat -d 1 یا iotop -oPa پیدا کنید
await بالا ولی aqu-sz کوچک خود دستگاه کند است (خرابی، RAID rebuild، SAN) smartctl ، /proc/mdstat ، لاگ کرنل
فقط w_await بالا فشار نوشتن / sync / journal بررسی fsync برنامه، Dirty
r/s بالا با rareq-sz کوچک خواندن تصادفی زیاد (مثلاً دیتابیس بدون index) بررسی کوئری/کش برنامه

CPU: وقفه، context switch و throttle

pidstat -w 1 3                        # cswch/s و nvcswch/s هر پردازش
mpstat -I SUM 1 3                     # نرخ وقفه
watch -d -n1 'cat /proc/softirqs'     # کدام softirq افزایش دارد (NET_RX = بار شبکه)
lscpu | grep -iE 'model name|mhz'
grep -H . /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null
sudo dmesg -T | grep -i throttl

NET_RX بالا روی یک هسته ← ترافیک شبکه روی یک CPU جمع شده (RSS/IRQ affinity). governor روی powersave در سرور تحت بار، یا پیام throttle، یعنی CPU عمداً کند شده است.

مشکل گذرا: ثبت شواهد با زمان‌بندی محدود

برای مشکلی که «گاهی» رخ می‌دهد، به‌جای نشستن پای ترمینال، ۵ دقیقه ثبت خودکار بگیرید و بعد بخوانید:

d=/var/tmp/perf-$(date +%F-%H%M); mkdir -p "$d"
( timeout 300 vmstat -t 5 > "$d/vmstat.txt" &
  timeout 300 iostat -xzt 5 > "$d/iostat.txt" &
  timeout 300 pidstat -ruw -h 5 > "$d/pidstat.txt" &
  wait )
ls -l "$d"

دستورها با timeout محدود شده‌اند تا فراموش‌شده نمانند. پس از تحلیل، پوشه را پاک کنید یا همراه تیکت آرشیو کنید.

baseline: «عادی» چه عددی است؟

بدون عدد عادی، «load ۸ بد است؟» جواب ندارد. برای هر سرور مهم یک بار در ماه این‌ها را در ویکی ثبت کنید: load ساعات اوج و غیراوج (sar -q)، available حافظه، await دیسک اصلی، تعداد اتصال (ss -s)، و ساعت‌های پیک (sar -u). مقایسهٔ هر رخداد با همین عددهاست که «کند شده» را به «۳ برابر baseline» تبدیل می‌کند.

جمع‌آوری وضعیت سریع

date
uptime
free -h
df -hT
df -ih
ip -br a
ss -s
systemctl --failed

این مجموعه برای snapshot اولیه مناسب است، اما خروجی آن به‌تنهایی علت ریشه‌ای را مشخص نمی‌کند. نسخهٔ کامل: scripts/incident-snapshot.sh.

ردیابی عمیق (با احتیاط)

sudo strace -c -f -p PID -o /var/tmp/strace.txt   # با Ctrl+C تمام کنید؛ خلاصهٔ syscall ها
sudo strace -f -tt -e trace=network -p PID         # فقط تماس‌های شبکه
sudo perf top                                       # توابع پرمصرف CPU (بسته linux-tools)

strace روی پردازش production می‌تواند آن را چندبرابر کند؛ کوتاه و با فیلتر.

نشانه ← علت محتمل

نشانه علت محتمل بررسی
load بالا، CPU بیکار I/O یا NFS vmstat (wa,b) ، iostat -x ، پردازش D
سرور بعد از ساعتی کند می‌شود نشت حافظه/فایل/اتصال ps --sort=-rss ، ls /proc/PID/fd \| wc -l ، ss -s
پردازش ناگهان مرد OOM killer dmesg -T \| grep -i killed
Too many open files limit کم LimitNOFILE ، /proc/PID/limits
کند فقط ساعت‌های خاص cron/بکاپ/پیک ترافیک sar ، systemctl list-timers
latency شبکه بالا drop/retransmit ip -s link ، ss -ti ، sar -n ETCP
load بالا، چند پردازش در حالت D ذخیره‌ساز یا NFS گیر کرده ps -eo state,pid,wchan:32,comm ، hung task در لاگ کرنل
سرویس بدون پر شدن RAM کل کشته می‌شود سقف MemoryMax (cgroup) memory.events ، systemctl show -p MemoryMax
بار CPU ناشناخته بالا miner/نفوذ top ، ps auxf ، امنیت

خلاصهٔ اجرایی

  1. USE: مصرف، صف، خطا برای هر منبع.
  2. load را با تعداد هسته و wa تفسیر کنید؛ available نه free.
  3. sysstat را فعال کنید تا سابقه داشته باشید.
  4. قبل از restart شواهد بگیرید؛ drop_caches راه‌حل نیست.
  5. مشکل گذرا را با ثبت ۵ دقیقه‌ای timeout شده بگیرید؛ baseline هر سرور مهم را ثبت کنید.