رم (RAM) چیست؟

رم (RAM) مخفف Random Access Memory یا «حافظه با دسترسی تصادفی» است؛ حافظه‌ای بسیار سریع و قابل خواندن و نوشتن که سیستم‌عامل، کد برنامه‌ها و داده‌هایی که همین حالا در حال پردازش‌اند در آن نگهداری می‌شوند. رم برخلاف دیسک فرّار (volatile) است؛ یعنی با قطع برق محتوای آن از بین می‌رود، و دقیقاً به همین دلیل نقش حافظه کاری سرور را دارد نه نقش انبار دائمی داده.

رم روی سرور دقیقاً چه کاری می‌کند؟

هر پردازه‌ای که روی سرور اجرا می‌شود، برای در اختیار داشتن کد و داده‌های خودش به فضایی در رم نیاز دارد: پردازه‌های وب‌سرور، اینترپرتر PHP یا Python، دیتابیس، سرویس کش و خود کرنل. پردازنده نمی‌تواند مستقیماً روی دیسک محاسبه کند؛ هر بایتی که قرار است پردازش شود اول باید به رم بیاید.

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

چرا رم معمولاً اولین گلوگاه سرورهای وب و دیتابیس است؟

در بارهای کاری وب و دیتابیس، معمولاً پیش از آنکه پردازنده اشباع شود، رم تمام می‌شود. دلیلش الگوی مصرف این سرویس‌هاست:

  • وب‌سرور و PHP-FPM: به ازای هر درخواست همزمان یک پردازه یا ترد فعال می‌شود که چند ده مگابایت رم مصرف می‌کند. مصرف تقریبی برابر است با تعداد پردازه‌های همزمان (pm.max_children) ضرب در میانگین مصرف هر پردازه. با افزایش ترافیک، این عدد خطی بالا می‌رود.
  • دیتابیس: MySQL/MariaDB و PostgreSQL برای اینکه سریع باشند، صفحات پرکاربرد جدول‌ها و ایندکس‌ها را در رم نگه می‌دارند (مثلاً innodb_buffer_pool_size در InnoDB). اگر این ناحیه از حجم دادهٔ فعال کوچک‌تر باشد، دیتابیس مجبور می‌شود مدام از دیسک بخواند و کوئری‌هایی که باید میلی‌ثانیه‌ای باشند کند می‌شوند.
  • لایهٔ کش: Redis و Memcached ذاتاً داده را در رم نگه می‌دارند؛ کمبود رم یعنی نرخ اصابت کش پایین و برگشتن فشار روی دیتابیس.

نتیجه این است که در بیشتر سرورهای مجازی که برای میزبانی سایت استفاده می‌شوند، افزودن رم بیش از افزودن هسته پردازنده باعث بهبود زمان پاسخ می‌شود — مگر آنکه بار کاری واقعاً محاسباتی باشد.

رم «آزاد» با رم «در دسترس» فرق دارد

یکی از رایج‌ترین سوءبرداشت‌ها این است که کاربر در خروجی free -m مقدار free را نزدیک صفر می‌بیند و نتیجه می‌گیرد سرور کم‌حافظه است. لینوکس رمی را که پردازه‌ها استفاده نمی‌کنند بلااستفاده رها نمی‌کند؛ آن را به page cache اختصاص می‌دهد تا فایل‌های پرکاربرد دوباره از دیسک خوانده نشوند، و به‌محض نیاز یک برنامه پس می‌گیرد.

رم یک سرور وب معمولاً بین این بخش‌ها تقسیم می‌شودبرنامه‌ها⁦PHP-FPM + Apache⁩پایگاه داده⁦MySQL / MariaDB⁩کش فایل‌سیستم⁦page cache⁩کرنل و سرویس‌ها⁦kernel + daemons⁩«رم آزاد» فقط بخش خاکستری است؛ کش فایل‌سیستم هر لحظه آزادشدنی استوقتی رم تمام می‌شودسواپ روی دیسککندی شدید⁦OOM Killer⁩قطع سرویسسواپ فقط ترمز اضطراری است، نه جایگزین رم

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

پس معیار درست ستون available است نه free؛ و روند مصرف را با vmstat 1 و top در طول زمان ببینید، نه در یک لحظه.

سواپ (Swap) چیست و کی خطرناک می‌شود؟

سواپ فضایی روی دیسک است که کرنل صفحات کم‌استفادهٔ حافظه را به آن منتقل می‌کند تا رم فیزیکی برای کارهای فعال آزاد شود. وجود سواپ به‌خودی‌خود بد نیست و در بسیاری موارد جلوی کشته‌شدن ناگهانی سرویس‌ها را می‌گیرد.

مشکل از جایی شروع می‌شود که سرور به‌طور مداوم در حال جابه‌جایی صفحات باشد؛ حالتی که به آن thrashing می‌گویند. در این وضعیت لود سیستم بالا می‌رود، I/O دیسک اشباع می‌شود و سایت کند یا بی‌پاسخ می‌شود، در حالی که مصرف پردازنده لزوماً بالا نیست. ستون‌های si و so در خروجی vmstat دقیقاً همین جابه‌جایی را نشان می‌دهند؛ اگر این اعداد به‌طور پیوسته غیرصفر باشند، سرور واقعاً کمبود رم دارد. رفتار کرنل در تمایل به سواپ‌کردن با پارامتر vm.swappiness قابل تنظیم است، اما تنظیم این پارامتر جایگزین رم کافی نیست.

اگر رم و سواپ هر دو تمام شوند، کرنل سازوکاری به نام OOM Killer را فعال می‌کند و یکی از پردازه‌ها را می‌کشد تا سیستم زنده بماند. معمولاً قربانی، سنگین‌ترین پردازه یعنی دیتابیس است. پیام‌های مربوط به آن در dmesg و لاگ سیستم ثبت می‌شود و بررسی همین لاگ اولین کاری است که هنگام قطع‌شدن ناگهانی MySQL باید انجام دهید.

چقدر رم لازم دارم؟

عدد جهانی وجود ندارد، اما می‌توان منطقی تخمین زد. اجزا را جدا حساب کنید و جمع بزنید:

  • مصرف پایهٔ سیستم‌عامل و سرویس‌های همیشه‌روشن (SSH، کران، مانیتورینگ، کنترل‌پنل در صورت وجود).
  • حجم دادهٔ فعال دیتابیس؛ یعنی بخشی از داده که واقعاً مرتب خوانده می‌شود، نه کل حجم دیتابیس.
  • تعداد درخواست‌های همزمان ضرب در میانگین مصرف هر پردازهٔ اپلیکیشن.
  • حاشیهٔ اطمینان برای اوج ترافیک، بکاپ‌گیری و به‌روزرسانی‌ها. سروری که در حالت عادی روی مرز مصرف کار می‌کند، در اولین اوج ترافیک دچار سواپ می‌شود.

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

نکته‌ای دربارهٔ نوع رم

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

جمع‌بندی

رم حافظهٔ کاری سرور است و در بارهای وب و دیتابیس معمولاً پیش از پردازنده به سقف می‌رسد. پیش از ارتقا، مصرف واقعی را با free و vmstat اندازه بگیرید، ستون available را ملاک قرار دهید و به فعالیت سواپ توجه کنید؛ روش دیدن مشخصات و منابع سرور بقیه دستورهای لازم برای پردازنده و فضای دیسک را هم آورده است؛ گاهی به‌جای رم بیشتر، تنظیم درست بافرپول دیتابیس یا تعداد پردازه‌های PHP-FPM مشکل را حل می‌کند. اگر ترجیح می‌دهید این تنظیم‌ها و پایش مصرف را تیم فنی انجام دهد، خدمات پشتیبانی و مدیریت سرور و مشاورهٔ زیرساخت برای همین کار در نظر گرفته شده‌اند.