اگر free -h را روی سرور خود اجرا کنید و ببینید چند صد مگابایت Swap در حال استفاده است، نخستین واکنش بسیاری از مدیران این است که «حافظه کم آمده». اما Swap در لینوکس فقط جایگزین RAM نیست؛ بخشی از استراتژی مدیریت حافظهٔ کرنل است که اگر درست تنظیم شود، از کشته شدن MySQL توسط OOM Killer جلوگیری می‌کند و اگر غلط تنظیم شود، سرور را به حالتی می‌برد که حتی SSH هم پاسخ نمی‌دهد. در این مقاله می‌بینیم Swap دقیقاً چه زمانی استفاده می‌شود، چه مقدار برای سرور وب یا دیتابیس لازم است، فایل Swap را چگونه بسازیم و swappiness و zram را چطور تنظیم کنیم.

Swap چیست و کرنل چه زمانی سراغ آن می‌رود

Swap فضایی روی دیسک (فایل یا پارتیشن) است که کرنل صفحات حافظه (page، معمولاً 4 کیلوبایت) را هنگام فشار حافظه به آن منتقل می‌کند. برخلاف تصور رایج، کرنل منتظر پر شدن کامل RAM نمی‌ماند؛ الگوریتم بازیابی حافظه بین دو گزینه انتخاب می‌کند: آزاد کردن page cache (کش فایل‌هایی که به‌راحتی دوباره از دیسک خوانده می‌شوند) یا انتقال صفحات «بی‌نام» (anonymous، یعنی حافظهٔ heap و stack برنامه‌ها) به Swap. صفحاتی که برنامه هفته‌هاست به آن‌ها دست نزده، مثل بخش‌هایی از یک دیمن که فقط هنگام راه‌اندازی اجرا می‌شود، کاندیدای طبیعی Swap هستند و خارج کردن آن‌ها از RAM فضای بیشتری برای کش دیسک آزاد می‌کند.

تفاوت «استفاده از Swap» با «کمبود RAM»

عدد استفاده از Swap به‌تنهایی معنای مشکل نیست. آنچه اهمیت دارد نرخ ورود و خروج صفحات است؛ ستون‌های si و so در خروجی vmstat 1 اگر به‌طور مداوم بالای صفر باشند، سرور در حال thrashing است و هر عملیات به دیسک وابسته شده است. اما اگر 500 مگابایت Swap اشغال شده و si/so صفر هستند، کرنل صرفاً حافظهٔ بی‌استفاده را کنار گذاشته و این کاملاً سالم است.

بدون Swap چه اتفاقی می‌افتد

سروری که Swap ندارد، در لحظهٔ فشار حافظه هیچ حاشیه‌ای ندارد: کرنل ابتدا page cache را تا حد صفر می‌کاهد و سپس OOM Killer پروسه‌ای را که بیشترین حافظه را دارد، یعنی معمولاً MySQL یا PHP-FPM، می‌کشد. حتی 1 گیگابایت Swap این لحظه را از یک قطعی ناگهانی به یک کندی قابل هشدار تبدیل می‌کند. نگرانی از فرسایش SSD نیز بی‌مورد است؛ نوشتن Swap در سرور سالم ناچیز است.

چه مقدار Swap لازم است؟ قاعده‌های سرانگشتی برای سرورها

فرمول قدیمی «دو برابر RAM» متعلق به دورانی است که سرورها 512 مگابایت حافظه داشتند. برای سرورهای امروزی که hibernate ندارند، مقادیر زیر یک نقطهٔ شروع منطقی است و نه قانون مطلق:

RAM سرورSwap پیشنهادیتوضیح
تا 2 GB2 برابر RAMسرور مجازی ارزان؛ Swap جلوی کرش هنگام به‌روزرسانی یا بیلد را می‌گیرد
2 تا 8 GBبرابر RAMوب‌سرور معمولی با PHP-FPM و MySQL روی یک ماشین
8 تا 64 GB4 تا 8 GBحاشیهٔ امن کافی است؛ بیشتر از این فقط thrashing را طولانی می‌کند
بیش از 64 GB4 GB (یا هیچ)برای دیتابیس اختصاصی با مانیتورینگ دقیق

سرور وب در برابر سرور دیتابیس

برای وب‌سرور که ده‌ها پروسهٔ PHP-FPM یا Node دارد، Swap بزرگ‌تر منطقی است چون بسیاری از این پروسه‌ها اغلب بیکارند. برای سرور دیتابیس اختصاصی برعکس است: اگر InnoDB Buffer Pool به Swap برود، هر کوئری چند صد برابر کندتر می‌شود؛ بنابراین Swap کوچک به‌عنوان بالشتک اضطراری کافی است و باید با swappiness پایین همراه شود. نصب‌کنندهٔ Ubuntu Server 24.04 به‌طور پیش‌فرض فایل /swap.img می‌سازد، اما ایمیج‌های ابری که بیشتر ارائه‌دهندگان استفاده می‌کنند، معمولاً هیچ Swap ندارند؛ بنابراین نخستین کار بعد از تحویل سرور مجازی، اجرای swapon --show است.

فایل Swap یا پارتیشن Swap؟

در کرنل‌های مدرن تفاوت عملکرد بین فایل و پارتیشن عملاً صفر است، چون کرنل نگاشت بلاک‌های فایل را یک‌بار در لحظهٔ swapon می‌خواند و دیگر از فایل‌سیستم عبور نمی‌کند. فایل Swap مزیت بزرگ‌تری دارد: بدون پارتیشن‌بندی مجدد قابل بزرگ یا کوچک شدن است و روی سرور مجازی که فقط یک دیسک دارد، تنها گزینهٔ عملی است.

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

روی ext4 و XFS می‌توانید فایل را با fallocate بسازید. روی Btrfs باید ابتدا ویژگی Copy-on-Write را برای فایل غیرفعال کنید (chattr +C) و از کرنل 5.0 به بعد Swap روی Btrfs پشتیبانی می‌شود. روی فایل‌سیستم‌های شبکه‌ای و فایل‌های دارای حفره (sparse) Swap اصلاً کار نمی‌کند؛ اگر swapon خطای «skip file with holes» داد، فایل را با dd بسازید.

ساخت فایل Swap گام‌به‌گام

  1. فایل را با اندازهٔ دلخواه بسازید و دسترسی آن را محدود کنید؛ فایل Swap قابل خواندن توسط همه، حافظهٔ برنامه‌ها را افشا می‌کند.
  2. فایل را به‌عنوان Swap قالب‌بندی و فعال کنید.
  3. آن را در /etc/fstab ثبت کنید تا بعد از ریبوت فعال بماند.
  4. با swapon --show و free -h نتیجه را تأیید کنید.
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
swapon --show

برای تغییر اندازه، ابتدا swapoff /swapfile را اجرا کنید (که ممکن است چند دقیقه طول بکشد چون محتویات باید به RAM برگردد)، سپس فایل را حذف و با اندازهٔ جدید بسازید. اگر RAM آزاد کافی برای بازگرداندن محتویات وجود ندارد، swapoff شکست می‌خورد؛ در این حالت ابتدا یک فایل Swap دوم بسازید.

تنظیم vm.swappiness و رفتار کرنل

پارامتر vm.swappiness به کرنل می‌گوید در زمان بازیابی حافظه چقدر به Swap کردن صفحات بی‌نام در مقابل آزاد کردن page cache تمایل داشته باشد. مقدار پیش‌فرض 60 برای دسکتاپ طراحی شده است؛ 10 برای سرور دیتابیس و 20 تا 30 برای وب‌سرور نقطهٔ شروع رایجی است. مقدار صفر Swap را غیرفعال نمی‌کند، بلکه آن را به آخرین راه‌حل قبل از OOM تبدیل می‌کند و همین رفتار باعث می‌شود در لحظهٔ فشار، ناگهان حجم زیادی به دیسک ریخته شود؛ به همین دلیل صفر معمولاً انتخاب خوبی نیست. از کرنل 5.8 مقادیر تا 200 نیز پذیرفته می‌شوند که برای Swap روی zram یا NVMe بسیار سریع معنا دارد.

sysctl vm.swappiness
echo 'vm.swappiness = 10' > /etc/sysctl.d/80-swap.conf
sysctl --system

vm.vfs_cache_pressure

این پارامتر (پیش‌فرض 100) تمایل کرنل به آزاد کردن کش inode و dentry را تعیین می‌کند. برای سرورهای هاست با میلیون‌ها فایل، کاهش آن به 50 باعث می‌شود متادیتای فایل‌ها بیشتر در حافظه بماند و پیمایش دایرکتوری‌ها سریع‌تر باشد.

محدود کردن Swap برای یک سرویس خاص

با cgroup v2 که در Ubuntu 24.04 و AlmaLinux 9 پیش‌فرض است، می‌توانید در فایل unit یک سرویس systemd گزینهٔ MemorySwapMax=0 را بگذارید تا آن سرویس هرگز به Swap نرود، در حالی که سایر پروسه‌ها از Swap استفاده می‌کنند. این روش برای Redis یا MySQL بسیار کارآمدتر از غیرفعال کردن Swap کل سرور است.

zram و zswap: Swap فشرده در حافظه

zram یک دستگاه بلاکی در RAM می‌سازد که محتوای آن با الگوریتم‌هایی مثل lz4 یا zstd فشرده می‌شود؛ صفحاتی که به آن Swap می‌شوند معمولاً به یک‌سوم تا یک‌چهارم حجم اصلی می‌رسند. برای سرور مجازی با 1 یا 2 گیگابایت RAM و دیسک کند، zram اغلب بهتر از فایل Swap عمل می‌کند. در Ubuntu بستهٔ zram-tools سرویس zramswap را فراهم می‌کند و در فایل /etc/default/zramswap می‌توانید ALGO=zstd و PERCENT=50 را تنظیم کنید. zswap متفاوت است: کش فشردهٔ میانی جلوی Swap دیسکی است و تنها با وجود Swap معمولی کار می‌کند. ترکیب zram با swappiness بالاتر (100 تا 150) منطقی است، اما برای سرورهایی که CPU آن‌ها اشباع است مناسب نیست.

مانیتورینگ Swap و تشخیص مشکل واقعی

سه ابزار برای تصمیم‌گیری کافی است. free -h تصویر کلی را می‌دهد؛ vmstat 1 10 ستون‌های si و so را نشان می‌دهد که نرخ ورود و خروج (کیلوبایت در ثانیه) است؛ و برای یافتن این‌که کدام پروسه چقدر در Swap است، فیلد VmSwap در /proc/PID/status یا ابزار smem را بررسی کنید. اگر MySQL چند گیگابایت در Swap دارد، innodb_buffer_pool_size بیش از حد بزرگ تنظیم شده و باید کاهش یابد؛ Swap در این حالت نشانهٔ مشکل است، نه علت آن.

for p in /proc/[0-9]*; do
  awk -v p="$p" '/VmSwap/ && $2 > 0 {print $2, p}' "$p/status" 2>/dev/null
done | sort -rn | head

اگر مدیریت روزانهٔ این موارد را نمی‌خواهید خودتان انجام دهید، سرویس مدیریت سرور می‌تواند پایش حافظه و تنظیم این پارامترها را بر عهده بگیرد.

جمع‌بندی

Swap یک بالشتک ایمنی است، نه جایگزین RAM. برای اغلب سرورها 2 تا 8 گیگابایت فایل Swap با swappiness بین 10 تا 30 کافی است، برای سرورهای کم‌حافظه zram گزینهٔ بهتری است و برای سرویس‌های حساس مثل MySQL می‌توان با MemorySwapMax کنترل دقیق‌تری اعمال کرد. مهم‌تر از عدد Swap، پایش si/so است: تا وقتی صفر هستند، مشکلی وجود ندارد.

سوالات متداول

آیا سرور با 16 گیگابایت RAM به Swap نیاز دارد؟

بله، 4 گیگابایت Swap با swappiness پایین پیشنهاد می‌شود. این مقدار حافظهٔ پروسه‌های بیکار را آزاد می‌کند و در اوج مصرف، به‌جای کشته شدن ناگهانی سرویس، فرصت واکنش می‌دهد.

چرا با وجود RAM خالی، Swap استفاده شده است؟

کرنل صفحاتی را که مدت‌ها لمس نشده‌اند به Swap می‌برد تا RAM را به کش دیسک اختصاص دهد. این رفتار طبیعی است و تا زمانی که ستون‌های si و so در vmstat صفر هستند، نشانهٔ مشکل نیست.

فایل Swap بهتر است یا پارتیشن؟

در کرنل‌های مدرن عملکرد یکسان است. فایل Swap به‌سادگی قابل تغییر اندازه است و روی سرور مجازی عملاً تنها گزینه محسوب می‌شود.

چگونه Swap را بدون ریبوت خالی کنیم؟

با اجرای swapoff -a و سپس swapon -a محتویات Swap به RAM برمی‌گردد. پیش از آن مطمئن شوید RAM آزاد کافی دارید، وگرنه swapoff شکست می‌خورد یا OOM Killer فعال می‌شود.

آیا zram جایگزین کامل فایل Swap است؟

برای سرورهای کم‌حافظه با CPU آزاد، بله. برای سرورهای بزرگ بهتر است zram با اولویت بالاتر و یک فایل Swap کوچک با اولویت پایین‌تر را با هم داشته باشید تا در شرایط بحرانی حافظهٔ zram هم تمام نشود.