Linux VPS一键添加删除Swap虚拟内存

Linux VPS一键添加/删除Swap虚拟内存

什么是 Swap 虚拟内存

Swap(交换分区/交换文件)是 Linux 系统在物理内存不足时,将磁盘空间临时充当内存使用的机制。对于内存较小的 VPS,适当配置 Swap 可以避免进程因内存不足被 OOM Killer 杀掉,提升系统稳定性。本文使用一键脚本快速添加或删除 Swap,适合懒人或小白用户。

为什么小内存 VPS 一定要配 Swap:OOM Killer 与内存回收

Linux 的内存管理有几个关键概念,理解它们以后你就知道 Swap 到底解决什么问题。物理内存(RAM)分为匿名页(进程的堆栈、数据段)和文件页(可执行文件、缓存)。当可用内存下降时,内核会依次做三件事:回收可丢弃的 Page Cache、把长时间不用的匿名页换出到 Swap、如果仍然无法满足分配请求,就触发 OOM Killer 强制杀掉占用内存最多的进程。

很多人的 VPS 只买了 512M 或 1G 内存,跑一个 MySQL、Docker 或者某些面板程序时,缓存和匿名页很快把内存吃满,于是编译进程、数据库进程被直接 kill 掉,表现为网站 502、SSH 登录后命令莫名消失、服务反复重启。这类现象并不一定是程序有 Bug,而是内核在内存压力下做出了保护性选择。配置 Swap 之后,内核多了一层缓冲:内存吃紧时先把冷数据换出到磁盘,给热数据腾出空间,避免直接触发 OOM。

需要强调 Swap 的边界:它的读写速度取决于磁盘 IO,机械盘和普通 SSD 上比内存慢几个数量级,NVMe 上也只是缩小了差距,不可能达到内存的延迟。因此 Swap 只能缓解内存不足,不能把 1G 内存变成 2G 内存。正确的定位是"保险丝"而不是"发动机":它让系统在高峰期不崩,而不是让系统跑得更快。

运行脚本前的准备

在动手之前,先确认三件事,避免脚本执行到一半失败:

  • 确认虚拟化架构。运行 systemd-detect-virtvirt-what,返回 openvz 说明是 OpenVZ 容器,无法自行创建 Swap,脚本会自动退出;返回 kvmxenvmwarenone 可以正常使用。
  • 确认磁盘剩余空间。Swap 文件要占用真实的磁盘空间,用 df -h / 检查根分区剩余容量,至少留出计划 Swap 大小的两倍(Swap 文件本身加正常运行余量)。
  • 确认当前没有已有 Swap。free -mswapon --show 查看,已经存在 Swap 的设备(如 /dev/vda2)时不要重复添加,否则会出现重复换出的问题。

另外建议以 root 身份执行,或在命令前加 sudo;脚本会修改 /etc/fstab 并调用 mkswapswapon,这些操作都需要特权。

脚本说明

 

说明:很多人的VPS服务器由于内存太小,会导致很多进程被杀掉,这时候就需要我们添加Swap虚拟内存了,这里就整了个一键脚本方便懒人或小白使用。

脚本

提示:脚本不支持OpenVZ架构,安装会自动退出。

运行命令:

wget https://www.moerats.com/usr/shell/swap.sh && bash swap.sh

然后根据选项进行操作,记得添加swap的时候填写纯数字,默认单位为M

脚本运行过程与交互示例

执行上面的命令后,脚本会先检测系统架构和内存大小,然后给出菜单。典型流程是选择"添加 Swap"、输入大小、等待格式化完成。整个过程输出大致如下:

# wget https://www.moerats.com/usr/shell/swap.sh && bash swap.sh
请输入数字来选择操作:
1. 添加 Swap
2. 删除 Swap
3. 退出
请输入你的选择: 1
请输入 Swap 大小(M): 2048
正在创建 /swapfile, 大小 2048M ...
setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=2f0a6c1d-9f2b-4e77-a1c3-8d5b6e4f7a10
已添加 Swap, 当前状态:
               total        used        free
Swap:           2047           0        2047
是否写入 /etc/fstab 以便开机自动挂载? [y/n]: y

看到 Swap: 2047 0 2047 就说明生效了。如果脚本停在 "setting up swapspace" 之后没有继续,通常是磁盘空间不足或权限不对,检查 df -h 和当前用户身份即可。整个过程中 /swapfile 会被创建,权限被设置为 600(只有 root 可读写,这是必须的,否则内核会拒绝启用)。

脚本背后做了什么:手动创建 Swap 的等价命令

一键脚本本质上是把下面这几步串起来。理解每条命令的作用,你才能在没有脚本的机器上(例如不允许下载外部脚本的生产服务器)自己完成配置:

# 1. 创建指定大小的交换文件(下面示例为 2G)
sudo fallocate -l 2G /swapfile
# 如果文件系统不支持 fallocate(如部分 ext3/老内核),用 dd 代替:
# sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

# 2. 收紧权限,只允许 root 访问
sudo chmod 600 /swapfile

# 3. 格式化为 swap 类型
sudo mkswap /swapfile

# 4. 立即启用
sudo swapon /swapfile

# 5. 写入 /etc/fstab 实现开机自动挂载
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

第 5 步很关键,也是最多人漏掉的一步:不写 /etc/fstabswapon 只在当前这次启动内有效,重启后 Swap 就消失了。反过来,如果要在已有 Swap 的机器上调整大小,必须先 swapoff 再删除文件,不能直接覆盖正在使用的 Swap 文件。

如果服务器上还没有安装完系统、而是在安装阶段规划分区,也可以在 fdisk/parted 里划分一个类型为 82 (Linux swap) 的分区,然后用 mkswap /dev/vdb1swapon 启用。分区 Swap 的 IO 通常比文件 Swap 略好,但扩容不如文件灵活,云主机上使用 /swapfile 更常见。

如何验证 Swap 是否真的生效

添加完成后不要只看脚本输出,用下面几条命令交叉确认:

free -m                     # 查看 Swap 总量与使用量
swapon --show               # 列出当前启用的交换设备(推荐)
cat /proc/swaps             # 内核视角的交换设备信息
cat /proc/sys/vm/swappiness # 当前换出倾向
sysctl vm.swappiness

正常输出应该是这样:

$ swapon --show
NAME      TYPE  SIZE  USED PRIO
/swapfile file    2G    0B   -2

$ free -m
               total        used        free      shared  buff/cache   available
Mem:             982         412         118          12         451         421
Swap:           2047           0        2047

三个常见判读错误:第一,free 里 Swap 的 "used" 长期为 0 并不代表 Swap 没生效——只有当内存压力和换出策略同时满足时才会真正写入,USED 为 0 完全正常;第二,容器(Docker/LXC)内部看到的 /proc/swaps 可能被 cgroup 限制,要在宿主机上验证;第三,如果 swapon --show 列表为空但 free 显示有 Swap,说明 Swap 来自系统自带的 zram 或分区,这种情况下新增文件 Swap 属于叠加,需要确认优先级(PRIO)是否冲突。

删除 Swap:关闭、删除文件并清理 fstab

换到内存更大的机型、或者发现 Swap 反而拖慢了系统时,需要把 Swap 干净地移除。删除不是简单删掉文件——正在被内核使用的交换文件无法直接删除:

# 1. 关闭指定的 Swap(必须先关闭)
sudo swapoff /swapfile

# 2. 确认已经不再使用
swapon --show          # 应输出为空或不再包含 /swapfile

# 3. 删除交换文件
sudo rm -f /swapfile

# 4. 删除 /etc/fstab 中对应的行
sudo sed -i '\|/swapfile|d' /etc/fstab

# 5. 再次确认
free -m

注意第 1 步的 swapoff 可能瞬间很慢:内核要把所有换出的页重新读回内存,如果物理内存已经被占满,这一步会长时间无响应,甚至触发 OOM。稳妥的做法是先在低峰期执行,或者临时调高 vm.swappiness 让系统提前把冷页换回,再关闭。批量管理多台机器时,可以先 swapoff -a 关闭全部 Swap 再逐个删除,但要确认没有任何进程依赖换出页。

性能调优:swappiness 与 vfs_cache_pressure

默认情况下 Linux 的 vm.swappiness 是 60,含义是"内存压力相同的情况下,回收匿名页(换出到 Swap)相对回收文件页的权重"。对于数据库、Web 服务这类对延迟敏感的负载,适当降低可以让内核尽量留在物理内存里,只在真正紧急时换出:

# 临时生效(重启后恢复)
sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.vfs_cache_pressure=50

# 永久生效
echo 'vm.swappiness=10'            | sudo tee -a /etc/sysctl.conf
echo 'vm.vfs_cache_pressure=50'    | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

vm.swappiness 取值 0 到 100。设为 0 并不代表完全禁用 Swap,内核在内存严重不足时依然会换出;真正要彻底禁用必须 swapoff 或把 vm.swappiness 与 cgroup 的 memory.swap.max 一起控制。vm.vfs_cache_pressure 控制内核对 dentry 和 inode 缓存的回收强度,值越大越倾向于回收缓存,值越小越保留缓存;传统建议是降到 50 到 100 之间,在大量小文件读写的场景下能明显减少磁盘 IO。

如果你的 VPS 提供的是 SSD 或 NVMe,除了文件 Swap 之外还可以考虑 zram:内核把一部分内存压缩后当作块设备使用,压缩比通常在 2:1 到 3:1,读写不落盘,延迟远低于磁盘 Swap。对于 1G 内存的小机器,zram 加一个小容量 Swap 文件是比单纯加大 Swap 更优的组合,代价是消耗少量 CPU 做压缩解压。

注意事项

1. 脚本不支持 OpenVZ 架构(KVM/XEN 架构正常),安装会自动退出;2. 填写 Swap 大小时输入纯数字,默认单位为 M,例如需要 2G 就填 2048;3. Swap 建议大小为物理内存的 1-2 倍,内存 1G 以内的小鸡建议至少 1G Swap;4. Swap 本质是磁盘空间,读写速度远低于内存,只能缓解内存不足,不能替代加内存;5. 添加后可通过 free -mswapon -s 验证 Swap 是否生效。

常见问题 FAQ

Q1:Swap 设置多大合适?经验值是物理内存的 1 到 2 倍。1G 以内的小内存机器建议至少 1G,常见做法是 1G 内存配 2G Swap;4G 以上内存的机器配 2G 到 4G 即可,因为此时主要是防止突发峰值,不需要靠 Swap 撑日常运行。内存越大,Swap 的相对比例应越小。

Q2:为什么添加了 Swap 还是被 OOM Killer 杀进程?Swap 只提供"备用空间",当峰值内存需求超过"物理内存 + Swap"的硬上限时,OOM Killer 依然会被触发。此外 Docker 容器默认的 --memory-swap 策略可能限制容器使用 Swap,需要在容器层面调整。排查时用 dmesg | grep -i "killed process" 确认被杀的具体进程和当时的内存快照。

Q3:Swap 会不会伤 SSD?现代 SSD 的写入寿命和主控磨损均衡算法足以承受常规规模的换出流量,真正容易伤盘的是频繁的大规模换入换出(即"内存长期不足导致 Swap 被反复读写")。如果观察到 Swap 的 used 长期居高且波动剧烈,正确做法是加内存或优化程序,而不是删掉 Swap。

Q4:能不能用 Swap 分区代替 Swap 文件?可以。分区的好处是吞吐略高,缺点是扩容麻烦、需要提前划分空间。绝大多数云主机和 VPS 场景用文件更灵活,本文脚本采用的也是文件方式。

Q5:如何监控 Swap 使用趋势?轻量方案是定时采集 free -m/proc/meminfo 中的 SwapTotal/SwapFree 字段,配合 vmstat 1 观察 si/so(换入/换出页数)。如果 si/so 持续为几百以上,说明系统已经进入 Swap 抖动状态,需要扩容或优化。

相关文章