کم بودن عدد «free» در Linux بهتنهایی نشانه مشکل نیست؛ سیستمعامل RAM بلااستفاده را برای cache فایلها مصرف میکند و در صورت نیاز پس میدهد. مسئله زمانی جدی است که available memory کاهش پایدار داشته باشد، swap و latency بالا برود، processها رشد کنترلنشده نشان دهند یا OOM Killer سرویس را ببندد.
پاسخ سریع: بهجای یک snapshot، روند زمانی available، swap و RSS processها را ببینید. مصرف را میان PHP-FPM، MySQL، Redis، وبسرور و jobهای CLI تفکیک کنید. سپس concurrency و سقف هر process را با RAM واقعی محاسبه کنید؛ restart فقط نمودار را موقتاً پاک میکند.
RAM سیستم با memory_limit PHP فرق دارد
memory_limit سقف یک پردازش PHP است، اما چند worker میتوانند همزمان حافظه مصرف کنند. MySQL bufferها، Redis، kernel و سرویسهای دیگر نیز سهم دارند. ممکن است یک درخواست به سقف PHP برسد در حالی که RAM سرور آزاد است، یا برعکس مجموع workerها سیستم را به OOM برسانند بدون اینکه هیچکدام به سقف فردی برسند.
برای خطای فردی PHP، راهنمای تمامشدن حافظه PHP را ببینید. این مقاله روی ظرفیت کل سرور تمرکز دارد.
اعداد free را چگونه بخوانیم؟
free -h
vmstat 1
ps -eo pid,ppid,cmd,rss,%mem --sort=-rss
در free ستون available از free خام مفیدتر است. vmstat جابهجایی swap و فشار لحظهای را نشان میدهد و ps processهای بزرگ را فهرست میکند. این ابزارها read-only هستند؛ چند نمونه در زمان مشکل بگیرید و اطلاعات command line حساس را پیش از اشتراک حذف کنید.
نشانه فشار واقعی حافظه
- افزایش مداوم swap-in/swap-out و کندی محسوس
- ثبت OOM یا killed process در kernel log
- restart شدن PHP-FPM، MySQL یا container
- رشد RSS یک process بدون بازگشت پس از پایان workload
- صف درخواست و timeout همزمان با افت available memory
- خطا هنگام backup، import یا job پرحجم
PHP-FPM چرا RAM زیادی میگیرد؟
هر worker کد، extension و داده درخواست را نگه میدارد. تعداد worker، نوع process manager، تنوع workload و مصرف peak تعیینکنندهاند. تخمین ظرفیت باید با RSS نمونههای واقعی در بار عادی و سنگین انجام شود؛ ضرب ساده یک سقف نظری در تعداد worker محافظهکارانه است، اما نادیده گرفتن concurrency نیز خطرناک است.
بالا بردن pm.max_children ممکن است صف را کوتاه کند ولی RAM را تمام کند. پایین آوردن افراطی نیز درخواستها را در صف نگه میدارد. recycling کنترلشده worker میتواند رشد ناشی از بعضی کتابخانهها را محدود کند، اما leak یا کد پرمصرف را درمان نمیکند.
MySQL و حافظه
بخشی از RAM دیتابیس برای buffer pool و cacheها عمداً استفاده میشود. این مصرف میتواند مفید باشد و کاهش بیدلیل آن I/O را بالا ببرد. در مقابل، bufferهای per-connection، connection زیاد و queryهای sort/join میتوانند با concurrency رشد کنند. تنظیم MySQL را جدا از PHP انجام ندهید؛ هر دو از RAM یک میزبان استفاده میکنند.
اگر query، lock یا schema خطا دارد، راهنمای خطاهای MySQL وردپرس را بررسی کنید. افزایش RAM جای index یا query درست را نمیگیرد.
Redis و Object Cache
Redis برای نگهداری داده در حافظه طراحی شده است؛ پس مصرف RAM آن به خودی خود خطا نیست. مشکل زمانی است که سیاست eviction، سقف حافظه، TTL یا namespace مناسب نباشد. اشتراک Redis میان چند سایت بدون جداسازی درست نیز خطر collision یا تخلیه داده سرویس دیگر را دارد.
object cache نباید داده بدون محدودیت یا objectهای بسیار بزرگ را انباشته کند. hit rate، کلیدهای بزرگ و eviction را بسنجید. پاک کردن دورهای کل cache نشانه پیکربندی سالم نیست و میتواند load دیتابیس را ناگهان بالا ببرد.
Jobهای خط فرمان و پردازشهای بزرگ
backup، import، thumbnail generation، scan و export ممکن است خارج از pool وب اجرا شوند. بنابراین dashboard PHP-FPM همه مصرف را نشان نمیدهد. process tree، cron و containerهای جانبی را ببینید. job را batch کنید و از overlap جلوگیری کنید؛ اجرای دوباره job تراکنشی باید از نظر idempotency بررسی شود.
روند تشخیص
- زمان و الگوی رشد RAM را از مانیتورینگ استخراج کنید.
- RSS را بر اساس سرویس و process گروهبندی کنید.
- ترافیک، cron، backup و deployment همان بازه را تطبیق دهید.
- swap، OOM و restart را در log سیستم بررسی کنید.
- برای PHP، endpoint و peak request را در staging profile کنید.
- برای MySQL و Redis، cache مفید را از رشد بدون سقف جدا کنید.
- پس از تغییر، available memory، latency و error rate را دوباره بسنجید.
مهار کمریسک در حادثه
اگر OOM نزدیک است، ابتدا job غیرحیاتی و مشخص را متوقف، ترافیک مخرب را هدفمند محدود یا ظرفیت موقت اضافه کنید. kill تصادفی MySQL یا حذف فایل swap میتواند قطعی و آسیب داده ایجاد کند. قبل از restart، process و logها را ذخیره و برنامه بازگشت سرویس داشته باشید.
اشتباههای رایج
- قضاوت از روی ستون free بدون توجه به available و cache
- restart دورهای بهجای یافتن روند رشد
- افزایش همزمان worker و memory_limit
- کاهش buffer دیتابیس بدون سنجش I/O
- پاککردن Redis بهصورت زمانبندیشده
- نادیده گرفتن processهای CLI و backup
پیشگیری
برای available memory، swap، OOM، RSS سرویسها و restart alert بسازید. ظرفیت را با peak ترافیک و jobهای همزمان آزمایش کنید. backup و import بزرگ را در پنجره مناسب اجرا و deployment را با baseline منابع مقایسه کنید. حاشیه امن برای kernel و spikeها باقی بگذارید.
چه زمانی کمک تخصصی لازم است؟
اگر مصرف پیوسته رشد میکند، OOM سرویسها را میبندد یا تنظیم PHP و MySQL بر یکدیگر اثر گذاشتهاند، restartهای مکرر ریسک قطعی را بالا میبرند. سرویس افزایش سرعت وردپرس میتواند مدل ظرفیت و منبع واقعی مصرف RAM را مشخص کند.
پرسشهای متداول
آیا RAM تقریباً پر در Linux بد است؟
نه الزاماً؛ cache سیستم مفید است. available، swap، reclaim و latency را بررسی کنید.
آیا افزودن RAM مشکل را حل میکند؟
برای ظرفیت واقعی مفید است، اما leak، job همپوشان یا تنظیم بیحد را فقط دیرتر آشکار میکند.
چرا بعد از restart مصرف کم میشود و برمیگردد؟
cacheها دوباره گرم میشوند یا workload/leak تکرار میشود؛ روند و process عامل باید مشخص شود.