Skip to Content

چگونه علت مصرف RAM بالای سرور را پیدا کنیم؟ تفسیر Cache، Process و OOM

مصرف RAM لینوکس را با available، cache، swap، RSS/PSS، process، container و OOM تحلیل کنید و memory leak را از استفاده طبیعی حافظه جدا کنید.

نویسنده مدیر کل تاریخ انتشار
این پست را به اشتراک بگذارید

دیدن RAM نزدیک ۱۰۰٪ در لینوکس الزاماً به معنی کمبود حافظه نیست. سیستم از حافظه آزاد برای page cache استفاده می‌کند و در صورت نیاز آن را پس می‌گیرد. نشانه مهم‌تر، مقدار available، رشد swap، reclaim شدید، OOM و کندی واقعی سرویس است. پاک کردن cache یا restart کور ممکن است فقط نمودار را موقتاً زیبا کند.

پاسخ سریع: خروجی free را با ستون available بخوانید، swap و رخدادهای OOM را بررسی کنید و processها را بر اساس RSS/PSS و روند زمانی مقایسه کنید. سپس حافظه را به سرویس، worker، container، cache یا kernel نسبت دهید. برای تشخیص leak به رشد پایدار در workload مشابه نیاز است، نه یک snapshot.

Free، Available و Cache چه فرقی دارند؟

حافظه free کاملاً بلااستفاده است؛ available برآوردی از حافظه قابل‌استفاده بدون فشار شدید است. buff/cache شامل داده‌ای است که می‌تواند عملکرد I/O را بهتر کند و بخشی از آن reclaim می‌شود. بنابراین دستورالعمل «هرچه cached بیشتر، بدتر» درست نیست.

free -h
cat /proc/meminfo
ps -eo pid,ppid,user,rss,vsz,%mem,etime,comm --sort=-rss | head -n 20
systemctl --failed

این فرمان‌ها خواندنی‌اند. VSZ فضای آدرس مجازی است و معادل RAM فیزیکی مصرف‌شده نیست. RSS صفحات resident را نشان می‌دهد اما صفحات shared ممکن است بین چند process چندبار شمرده شوند. برای دقت تجمیعی، PSS در ابزارهای سازگار مفیدتر است.

نشانه‌های فشار واقعی حافظه

  • available برای مدت معنادار پایین می‌ماند
  • swap-in/swap-out مداوم و latency بالا دیده می‌شود
  • OOM Killer processها را می‌بندد
  • workerها restart یا allocation error دارند
  • reclaim و I/O شدید پاسخ سرویس را کند می‌کند
  • container به limit خود می‌رسد، حتی اگر host حافظه داشته باشد

یک threshold ثابت برای همه سرورها مناسب نیست. workload دیتابیس عمداً cache بزرگی دارد؛ برنامه بدون cache نیز ممکن است burst کوتاه بسازد. baseline سالم همان سرویس معیار بهتری است.

مصرف را در طول زمان ببینید

Memory leak معمولاً با رشد تدریجی و بازنگشتن حافظه پس از پایان workload دیده می‌شود. نمودار process/container، deployها، request rate و jobها را هم‌زمان کنید. رشد RSS پس از warming cache ممکن است متوقف شود و leak نباشد. فقط با دو نقطه نزدیک نتیجه نگیرید.

Process پرمصرف را به سرویس وصل کنید

PID، parent، user، uptime و تعداد instanceها را ببینید. گاهی هیچ process منفردی بزرگ نیست اما صدها worker مجموع RAM را مصرف می‌کنند. command line می‌تواند secret داشته باشد و نباید عمومی شود. service manager یا container metadata مشخص می‌کند process از کجا ساخته شده است.

RSS، PSS و حافظه Shared

جمع ساده RSS processهای یک سرویس ممکن است کتابخانه‌های shared را چندبار حساب کند. PSS سهم متناسب صفحات shared را در نظر می‌گیرد، اما ابزار لازم ممکن است نصب نباشد و خواندن همه processها هزینه داشته باشد. برای تصمیم ظرفیت، metric سطح cgroup یا سرویس را نیز کنار اندازه process قرار دهید.

PHP-FPM و تعداد Worker

بودجه حافظه PHP-FPM تقریباً به تعداد process هم‌زمان و اندازه واقعی هر process وابسته است. memory_limit سقف بالقوه هر درخواست است، نه مصرف ثابت و نه سقف کل pool. ضرب تعداد worker در یک عدد حدسی می‌تواند ظرفیت را اشتباه نشان دهد؛ از نمونه‌های واقعی و حاشیه امن برای سیستم و دیتابیس استفاده کنید.

افزایش worker برای رفع صف، اگر RAM کافی نباشد، swap یا OOM می‌سازد. کاهش شدید worker نیز latency را بالا می‌برد. ظرفیت باید CPU، RAM، زمان درخواست و concurrency را با هم متعادل کند.

MySQL و Cache دیتابیس

دیتابیس از buffer/cache برای کاهش I/O استفاده می‌کند و مصرف بالای برنامه‌ریزی‌شده لزوماً leak نیست. در کنار buffer سراسری، برخی bufferها به connection یا عملیات وابسته‌اند و concurrency اهمیت دارد. template تنظیمات را کور اعمال نکنید؛ dataset، query، connection و RAM سایر سرویس‌ها را بسنجید.

Redis و Object Cache

Redis باید policy حافظه و رفتار هنگام رسیدن به سقف مشخص داشته باشد. dataset بدون limit می‌تواند RAM را بگیرد؛ limit خیلی پایین نیز eviction و miss زیاد ایجاد می‌کند. fragmentation، key growth و TTL را بررسی کنید. flush کردن کل cache روی production بار دیتابیس را ناگهان زیاد می‌کند و راه تشخیص نیست.

Container و Cgroup

container ممکن است به memory limit برسد و OOM شود، در حالی که free روی host هنوز available نشان می‌دهد. مصرف، limit، eventهای OOM و restart count را در سطح همان cgroup ببینید. برعکس، container بدون limit می‌تواند سرویس‌های دیگر host را تحت فشار قرار دهد.

حافظه Kernel، Slab و tmpfs

همه RAM در ستون processها دیده نمی‌شود. kernel slab، page table، network buffer، tmpfs و shared memory نیز مصرف دارند. اگر جمع processها با فشار سیستم هم‌خوان نیست، /proc/meminfo و metricهای kernel مسیر بعدی‌اند. تغییر sysctl بدون شناخت subsystem می‌تواند پایداری را بدتر کند.

Swap خوب است یا بد؟

وجود swap کوچک می‌تواند در spike فرصت واکنش بدهد، اما جای RAM و ظرفیت‌سنجی نیست. مقدار استفاده‌شده به‌تنهایی کافی نیست؛ نرخ swap-in/out و latency اهمیت دارد. خاموش کردن swap روی سرور تحت فشار ممکن است allocation را ناگهان شکست دهد؛ تغییر آن نیازمند ارزیابی memory و برنامه بازیابی است.

OOM Killer را بررسی کنید

kernel برای حفظ سیستم ممکن است processی را انتخاب و متوقف کند. journal و kernel log زمان، process و cgroup را نشان می‌دهند. process کشته‌شده الزاماً مقصر اصلی نیست؛ ممکن است فقط امتیاز انتخاب بالاتری داشته باشد. برای اصلاح باید منبع فشار، limitها و رفتار سرویس پیش از رخداد بررسی شود.

Memory Leak چگونه تأیید می‌شود؟

  1. نسخه برنامه و زمان deploy را ثبت کنید.
  2. workload قابل مقایسه انتخاب کنید.
  3. RSS/PSS یا cgroup memory را در زمان اندازه بگیرید.
  4. بعد از پایان workload و چرخه GC/cache رفتار را ببینید.
  5. نوع allocation را با profiler مناسب در staging بررسی کنید.
  6. fix یا rollback را با آزمون بار کنترل‌شده تأیید کنید.

profiler حافظه می‌تواند overhead و داده حساس ایجاد کند. فعال‌سازی دائمی روی production مناسب نیست مگر ابزار برای آن طراحی و اثرش سنجیده شده باشد.

وقتی RAM ناگهان بالا می‌رود

burst ترافیک، import، backup، cache warming، fork process، job تصویر یا Query بزرگ را روی timeline بررسی کنید. افزایش ناگهانی پس از deploy می‌تواند تغییر concurrency یا dependency باشد. اگر process هنوز کار معتبر انجام می‌دهد، kill آن ممکن است فایل یا تراکنش ناقص بسازد.

ترتیب اصلاح از کم‌ریسک تا پیشرفته

  1. اثر کاربر، available، swap و OOM را ثبت کنید.
  2. مصرف process، مجموع سرویس و container را مقایسه کنید.
  3. روند را با deploy، ترافیک و job تطبیق دهید.
  4. cache طبیعی را از رشد بدون سقف جدا کنید.
  5. concurrency و limit را با ظرفیت واقعی تنظیم کنید.
  6. leak را در staging profile و fix را تحت بار آزمون کنید.
  7. بعد از rollout، memory و latency را پایش کنید.

چه کارهایی نکنیم؟

  • پاک کردن page cache برای پایین آوردن نمودار
  • restart دوره‌ای به جای رفع leak
  • جمع RSS و اعلام نتیجه قطعی بدون shared memory
  • افزایش worker یا connection بدون بودجه
  • flush کردن Redis در ساعت کاری
  • خاموش کردن swap روی سیستم تحت فشار
  • kill کردن دیتابیس یا job write بدون شناخت
  • نصب profiler ناشناس روی production

پیشگیری و ظرفیت‌سنجی

available، swap activity، OOM، cgroup limit، RSS/PSS سرویس، queue و latency را مانیتور کنید. alert باید روند رشد و زمان تا exhaustion را نیز ببیند. deploy جدید را با canary یا rollout محدود و مقایسه memory قبل/بعد اجرا کنید. headroom برای spike، kernel و عملیات نگهداری کنار بگذارید.

چه زمانی کمک تخصصی لازم است؟

اگر memory پس از هر restart دوباره رشد می‌کند یا بین برنامه، دیتابیس، cache و kernel قابل نسبت دادن نیست، آزمون تصادفی می‌تواند OOM و قطعی بسازد. مدیریت ماهانه سرور می‌تواند مصرف را در سطح process و cgroup تحلیل و ظرفیت یا leak را با شواهد مشخص کند.

پرسش‌های متداول

چرا لینوکس تقریباً همه RAM را مصرف می‌کند؟

بخشی برای cache فایل استفاده می‌شود و قابل reclaim است؛ ستون available و فشار واقعی را بررسی کنید.

آیا خالی کردن Cache سرعت را بهتر می‌کند؟

معمولاً نه؛ cache برای کاهش I/O مفید است و پاک کردن آن حتی می‌تواند سرویس را موقتاً کندتر کند.

RAM بالا یعنی Memory Leak؟

نه. leak به روند رشد بازنگردنده در workload قابل مقایسه نیاز دارد؛ cache و dataset بزرگ رفتار دیگری دارند.

چقدر Swap مناسب است؟

عدد عمومی وجود ندارد؛ workload، latency قابل‌قبول و سیاست OOM تعیین‌کننده‌اند. swap جای RAM کافی نیست.

چگونه علت مصرف CPU بالای سرور را پیدا کنیم؟ از Load Average تا Process و Query
برای یافتن علت CPU بالای لینوکس، load، user/system/iowait/steal، process، thread، container، PHP و Query را در timeline رخداد بررسی کنید.