当云服务器ECS实例物理内存不足时,配置Swap(交换空间)是一种经济高效的应急方案。它利用磁盘空间作为虚拟内存,可以防止系统因偶发的内存峰值导致内存溢出(OOM)而崩溃,允许系统在物理内存耗尽时继续平稳运行。
开启swap分区可能会导致内存I/O性能下降。当ECS实例内存不足时,建议优先通过修改实例规格增加实例的物理内存。
对于普通云盘,不建议使用swap分区,因为其I/O性能较低,会导致性能下降和I/O瓶颈。其他类型云盘可根据实际情况使用swap分区,但应合理配置以避免频繁的swap分区操作,确保系统性能和稳定性。
操作步骤
步骤一:检查当前Swap状态
在开始配置前,确认系统当前没有已存在的Swap配置,避免冲突。
登录ECS实例。
访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。
进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示登录,进入终端页面。
查看swap分区的配置。
swapon --show若回显信息为空,表示系统未配置swap分区,可继续下一步。
若出现类似以下回显信息,表示系统已存在swap分区,可根据需要关闭swap分区,或在其他磁盘上创建新的Swap。

步骤二:创建并设置Swap文件
创建交换文件。
以创建1 GiB大小的
/swapfile为例。推荐使用fallocate命令,它可以瞬间分配文件空间,效率远高于dd。# 创建一个1 GiB大小的交换文件 sudo fallocate -l 1G /swapfile若文件系统(如早期XFS)不支持
fallocate,系统会提示fallocate failed: Operation not supported。此时,请改用dd命令创建,但耗时会更长。sudo dd if=/dev/zero of=/swapfile bs=1M count=1024of的值/swapfile是变量,表示交换分区的标识,可自定义设置,该变量值不能和已有分区标识相同。bs和count的值表示创建的交换文件的大小,可自定义设置,该命令中bs=1M count=1024表示设置交换文件的大小为1 GB。
设置安全权限。
防止非root用户读取可能包含敏感数据(如内存中的密码、密钥)的交换文件,将其权限设置为
600。sudo chmod 600 /swapfile将文件格式化为swap分区,即将文件标记为交换空间。
sudo mkswap /swapfile成功的回显信息类似:
Setting up swapspace version 1, size = 1 GiB (1073737728 bytes) no label, UUID=a1a7e24c-38f6-41a4-9e18-be60b631133a说明:创建的交换文件大小至少需要大于40 KB,否则
mkswap命令会报错。
步骤三:启用Swap并验证
激活创建的Swap文件,并确认系统已成功识别。
激活swap。
sudo swapon /swapfile验证Swap是否已开启。
swapon --show成功启用后,回显如下:
NAME TYPE SIZE USED PRIO /swapfile file 1G 0B -2或者使用
free -h查看,Swap行应显示总量。
步骤四:配置开机自动挂载(持久化)
将Swap配置写入/etc/fstab文件,确保实例重启后Swap依然生效。
(推荐)备份
fstab文件,以防误操作。sudo cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d)将Swap配置追加到
fstab文件。以下命令会先检查是否存在重复条目,避免重复添加。
SWAP_FILE_PATH="/swapfile" if ! grep -q "swap" /etc/fstab; then echo "${SWAP_FILE_PATH} none swap sw 0 0" | sudo tee -a /etc/fstab else echo "Swap entry already exists in /etc/fstab. No changes made." fi验证持久化配置。
无需重启实例,即可验证
/etc/fstab配置的正确性。# 1. 关闭所有Swap sudo swapoff -a # 2. 根据fstab内容重新挂载所有Swap sudo swapon -a # 3. 检查Swap是否已按预期重新挂载 swapon --show如果命令能正确输出Swap信息,则证明持久化配置成功。
优化与管理
调整Swap使用倾向(swappiness)
swappiness是Linux内核参数,用于控制系统使用Swap的积极程度,取值范围为0-100。
值越高:内核越倾向于使用Swap,尽早将不活跃的内存页换出到磁盘。
值越低:内核越“懒惰”,倾向于将内存页保留在物理内存中,直到物理内存严重不足时才使用Swap。
调整swap参数是一项需要谨慎操作的任务,不恰当的修改可能会导致系统性能下降或虚拟内存使用不符合预期,请根据实际业务场景并在充分了解参数作用的基础上谨慎操作。如不确定是否需要调整,建议保持默认配置。
场景化建议:
应用场景 | 推荐 | 技术原理 |
数据库 (MySQL, PostgreSQL) | 1-10 | 数据库对I/O延迟敏感,应尽可能避免其核心缓冲池被换出到Swap,以保证查询性能。 |
内存数据库 (Redis, Memcached) | 1 | 内存数据库对延迟极度敏感,任何Swap操作都可能严重影响性能。设为1表示仅在绝对必要时才使用Swap。 |
Web应用服务器 (Nginx, Apache) | 10-60 | 在响应速度和内存利用率之间取得平衡,允许将非核心的、不活跃的进程页换出。 |
默认/通用/批处理 | 60(系统默认值) | 适用于大多数通用场景,允许系统将非活跃的系统进程换出,为活动任务释放更多物理内存。 |
修改方法:
编辑
/etc/sysctl.conf文件,以物理内存少于10%时才使用swap分区为例,需要调整以下参数值。vm.swappiness=10保存并退出,然后执行以下命令使配置生效。
sudo sysctl -p验证
swappiness参数配置是否生效。cat /proc/sys/vm/swappiness如下回显信息表示
swappiness参数配置已生效。
监控Swap使用情况
监控目的 | 推荐命令 | 说明 |
查看总体内存和Swap使用量 |
| 最常用、最直观的命令。 |
实时监控Swap活动(换入/换出) |
| 关注 |
找出正在使用Swap的进程 | `for file in /proc/*/status; do awk '/VmSwap | Name/{printf 2""2""3}END{ print ""}' $file; done | grep -v "0 kB" | sort -k 2 -n -r` |
历史性能分析 |
|
|
关闭并清理Swap
在不再需要Swap时,安全地关闭并删除相关文件,释放磁盘空间。
关闭指定的Swap文件。
sudo swapoff /swapfile从
fstab中删除自动挂载配置。 使用sed命令可以安全地删除对应行,避免手动编辑出错。sudo sed -i '\|/swapfile|d' /etc/fstab删除交换文件,释放磁盘空间。
sudo rm /swapfile验证Swap是否已完全关闭。
执行
swapon --show或free -h,确认Swap信息已消失。
关闭swap分区
执行以下命令,关闭swap分区。
sudo swapoff /swapfile说明其中
/swapfile为swap分区标识,请您根据实际环境替换。编辑
etc/fstab文件,并删除类似以下的swap相关挂载信息,取消swap自动挂载。/swapfile none swap defaults 0 0保存并退出,然后执行以下命令,确认swap分区是否已经关闭。
swapon --show如果回显信息为空,表示系统已关闭swap分区。

常见问题
Swap使用不符合预期如何解决?
完成Swap分区的创建和swappiness参数的调整后,可能会发现一个令人困惑的现象:即便物理内存压力很大,Swap分区的使用率依然很低,似乎swappiness的设置没有生效。
问题诊断
这个问题的根源在于现代Linux发行版广泛使用的systemd和控制组(Cgroup)机制。
Cgroup的局部规则:在默认的Cgroup v1模式下,
systemd会为系统服务(system.slice)和用户会话(user.slice)等创建独立的Cgroup。每个Cgroup都可以拥有自己的资源控制参数,其中就包括memory.swappiness。局部覆盖全局:
systemd在初始化这些Cgroup时,会给它们设置一个默认的memory.swappiness值(通常是60)。这个Cgroup内部的设置,其优先级高于您在/etc/sysctl.conf中配置的全局vm.swappiness。结果:运行的程序,实际上遵循的是其所在Cgroup的
swappiness规则,而不是全局规则,导致全局配置失效。
快速验证
找一个正在运行的进程的PID(例如,
pidof nginx)。查看该进程所属的Cgroup:
cat /proc/[PID]/cgroup会看到类似
/system.slice/nginx.service的路径。查看这个Cgroup实际的
swappiness值:cat /sys/fs/cgroup/memory/system.slice/nginx.service/memory.swappiness将很可能看到输出是
60,即使已将全局vm.swappiness设为其他值,这就表明全局配置失效问题存在。
解决方案
方案一:切换到 Cgroup v2(推荐)
原理:Cgroup v2 修复了v1的诸多设计问题,采用统一的层级结构。在v2模式下,子Cgroup默认会继承父节点的配置。只需配置全局的vm.swappiness,该设置就能自动、统一地应用到系统中的所有进程。
操作步骤:
更新内核启动参数:
使用grubby工具,为所有内核添加systemd.unified_cgroup_hierarchy=1参数,以开启Cgroup v2。sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"说明:此命令是持久化的,它会修改GRUB引导配置,让系统在下次启动时以Cgroup v2模式初始化。
重启ECS实例:
该设置为内核级参数,必须重启才能生效。sudo reboot验证与配置:
验证:重启后,执行
mount | grep cgroup,如果看到类型为cgroup2的挂载点,说明已成功切换到Cgroup v2。配置:在
/etc/sysctl.conf中设置期望的vm.swappiness值,并通过sudo sysctl -p使其对整个系统生效。
方案二:在 Cgroup v1 环境下持久化配置(替代方案)
如果环境由于特殊原因(例如,运行着不兼容Cgroup v2的旧版容器软件)无法切换,可以使用systemd的覆盖配置(drop-in)来解决。
原理:不再依赖可能失效的全局配置,而是直接让systemd在创建核心slice时就使用指定的swappiness值。
操作步骤:
为
system.slice创建覆盖配置(影响所有系统服务):请将
60替换为期望的swappiness值。sudo mkdir -p /etc/systemd/system/system.slice.d/ sudo tee /etc/systemd/system/system.slice.d/99-swappiness.conf <<'EOF' [Slice] MemorySwappiness=60 EOF为
user.slice创建覆盖配置(影响所有用户登录会话)。请将
60替换为期望的swappiness值。sudo mkdir -p /etc/systemd/system/user.slice.d/ sudo tee /etc/systemd/system/user.slice.d/99-swappiness.conf <<'EOF' [Slice] MemorySwappiness=60 EOF重启使配置生效。
sudo systemctl daemon-reload sudo rebootdaemon-reload仅使systemd重载配置。为了确保所有服务和会话都在新的Slice配置下被创建,需重启服务器。