买服务器时经常看到"2G 内存 + 2G Swap"这类配置,很多人以为 Swap 是额外的内存,能当内存用,于是把它配得很大,结果服务器一卡就疯狂读写磁盘,反而更慢。也有人听说"Swap 会拖慢性能",干脆全部关掉,结果内存一紧张进程直接被 OOM 杀掉,业务中断。
Swap 到底该不该开、开多大、什么时候它是救命的、什么时候它是拖后腿的,这些问题没有一刀切的答案,取决于你的内存大小、磁盘类型和业务特征。这篇文章讲清楚 Swap 的作用和原理,给出不同场景下的大小建议和 vm.swappiness 的调法,手把手演示创建 swap 文件(包括 fallocate 和 dd 的坑),最后分析它对性能的真实影响,以及什么时候该用、什么时候不该用。
Swap 是什么,为什么需要它
Swap(交换空间)是磁盘上的一块区域,当物理内存不够用时,内核会把一些"暂时用不到"的内存页面挪到 Swap 上,腾出物理内存给更需要的进程。这个过程叫换出(swap out),需要时再换回(swap in)。
要理解两个关键点:
第一,Swap 不是内存的延伸,而是"内存不够时的缓冲垫"。 物理内存访问是纳秒级,SSD 是微秒级,机械盘是毫秒级,差了三到六个数量级。一旦开始频繁换入换出,程序性能会断崖式下跌。所以 Swap 的价值不在于"让内存变多",而在于:
- 让系统在内存暂时紧张时有个缓冲,不至于立刻 OOM,给运维争取处理时间;
- 把长期不活跃的冷数据(比如几个月没人访问的缓存页面)挪出去,给热点数据腾地方;
- 支持休眠(hibernation,把内存整体写入 Swap),服务器一般用不到。
第二,Linux 是"用多少算多少"的按需分配。 程序 malloc 一大块内存,内核通常只分配虚拟地址,真正读写时才实际分配物理页。所以即使所有进程声明的内存总和超过物理内存,只要实际用到的没超,系统照常运行。Swap 处理的正是"实际用量"超出物理内存的情况。
# 查看当前 swap 使用情况
free -h
swapon --show
cat /proc/swaps
free -h 输出里的 Swap 那一行就是全部信息:
total used free shared buff/cache available
Mem: 7.7G 2.1G 512M 128M 5.1G 5.2G
Swap: 2.0G 128M 1.9G
used 持续增长是内存压力的信号,但要结合 si/so 一起看——used 有值不一定在频繁交换,只有 si/so 持续非零才说明正在拖累性能。
现代服务器该配多大 Swap
老规矩是"内存 1 倍""内存 2 倍",那是机械盘时代、内存普遍很小的时候定的,今天已经不太适用。给几个参考方向(都是经验值,不是硬标准):
| 物理内存 | 传统建议 | 现代通用建议 | 说明 |
|---|---|---|---|
| < 2G | 2 倍内存 | 2G 左右 | 小机器内存紧张,Swap 是必要的保命垫 |
| 2G - 8G | 1 - 2 倍 | 2G - 4G | 常用区间,够缓冲即可 |
| 8G - 32G | 1 倍 | 2G - 8G | 内存够大,Swap 主要防突发 |
| 32G - 128G | 0.5 倍 | 4G - 8G | 越大越不必大配 |
| > 128G | 争议大 | 0 - 8G 或用 zram | 内存充裕的机器往往直接不配 Swap |
近年的实践趋势是:内存充足的服务器,Swap 可以配得小一点,甚至用 zram(压缩内存)替代。 原因是 SSD/NVMe 上的 Swap 设备能提供比机械盘快得多的换页速度,同时大内存机器本身很少触发交换。所谓 zram,是在内存里划一块区域做压缩块设备当 Swap 用,换出的页面先压缩再存,能存下更多内容,读写速度也远高于磁盘 Swap:
# 查看是否加载了 zram 模块
lsmod | grep zram
sudo modprobe zram
是否用 zram 取决于发行版是否已启用(很多桌面和容器发行版默认开了)。服务器上是否启用要结合业务评估,压缩会消耗 CPU。
对于绝大多数通用业务(Web、应用服务器、中小数据库),一个朴素的规则是:留一点点 Swap 做保命缓冲,别指望它扛容量。 配 2G 到 4G,把 swappiness 调低,让它平时不动,只在真紧张时兜底。
调整 swappiness
vm.swappiness 控制内核在不活跃时把内存换出去的积极程度,范围 0 到 100,默认 60。
# 查看当前值
cat /proc/sys/vm/swappiness
# 临时修改(重启失效)
sudo sysctl vm.swappiness=10
# 永久修改
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
这个值需要理解准确,因为网上有很多误传:
| 取值 | 行为 | 适用场景 |
|---|---|---|
| 0 | 尽量不换出匿名页(但内存紧张时仍可能交换,不是"禁止") | 数据库等对延迟敏感的服务 |
| 1 - 10 | 只在内存很紧张时才换出 | 数据库、缓存服务、低延迟业务 |
| 60(默认) | 平衡,正常回收 | 通用 Web、应用服务器 |
| 100 | 积极换出 | 极少用,除非内存极小且容忍慢 |
误区一:把 swappiness=0 当成"禁用 Swap"。它只是降低倾向,内存实在不够时内核仍然会换出,因为不换就 OOM。真要禁用是 swapoff。
误区二:在数据库服务器上直接设 0。有些数据库(如某些版本的 MySQL、Redis)会建议 swappiness 设 1 而不是 0,兼顾"尽量不换"和"内存真紧张时还有缓冲"。设 0 在极端情况下可能因匿名页无法换出而加速 OOM。
误区三:改了 /proc/sys/vm/swappiness 就以为永久生效。那是临时的,重启就没了,要写进 /etc/sysctl.d/。
创建 Swap:swap 文件实操
现在有一种趋势是用 swap 文件(swapfile)代替 swap 分区,因为它不用重新分区、随时能调大小,云服务器上几乎都这么干。步骤是:创建文件 → 格式化 → 启用 → 写 fstab。
方法一:fallocate(推荐,最快)
# 创建 4G 的 swap 文件(注意路径,/swapfile 是常见选择)
sudo fallocate -l 4G /swapfile
# 权限收紧,只有 root 能读写(重要!)
sudo chmod 600 /swapfile
# 格式化为 swap
sudo mkswap /swapfile
# 启用
sudo swapon /swapfile
# 验证
swapon --show
free -h
fallocate 是分配文件系统块,速度快,几乎瞬间完成。
方法二:dd(兼容性最好,但慢)
fallocate 在某些文件系统(比如旧的 XFS、部分网络文件系统)上可能不被支持,或者因为底层不支持 fallocate 而生成的文件有空洞,导致 swap 无法启用。这时用 dd 更稳妥,它真正写入数据:
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
dd 会实际写 4G 数据,慢一些,但避免了"空洞"问题。如果 fallocate 生成的 swap 文件启动时报 swapon: /swapfile: swapon failed: Invalid argument,多半就是空洞的锅,改用 dd 重建。
写入 fstab 实现开机自动启用
# 追加到 /etc/fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 验证 fstab 无误(避免写错导致重启失败)
sudo swapon --show
sudo findmnt --verify
风险提示:/etc/fstab 写错会导致开机卡在 emergency 模式。改完务必用 findmnt --verify 校验,或者给该项加 nofail 选项:/swapfile none swap sw,nofail 0 0。回滚就是编辑 fstab 删掉那一行,然后 swapoff /swapfile。
禁用与删除
# 停用某个 swap
sudo swapoff /swapfile
# 停止所有 swap(谨慎!会瞬间占用大量内存)
sudo swapoff -a
# 删除文件(确认已从 fstab 移除后)
sudo rm /swapfile
风险提示:swapoff -a 会把 Swap 上的内容全部读回内存,如果换出的数据比空闲物理内存还多,会触发 OOM 甚至卡死。执行前先确认 free -h 里 available 足够容纳 Swap used。
创建 Swap:交换分区(老派做法)
如果还没有分区、想用独立分区,可以这么操作(切勿对已有数据的分区操作):
# 查看磁盘与分区
lsblk
sudo fdisk -l /dev/sdb
# 用 fdisk 或 parted 建一个类型为 Linux swap 的分区(类型码 82)
sudo fdisk /dev/sdb
# 在 fdisk 里:n 新建 -> t 选类型 82 -> w 保存
# 格式化和启用
sudo mkswap /dev/sdb1
sudo swapon /dev/sdb1
# 写 fstab 用 UUID 更稳妥
sudo blkid /dev/sdb1
# /etc/fstab 中写:UUID=xxxx none swap sw 0 0
风险提示:分区操作是不可逆的高危动作,fdisk 写盘后分区表立即生效,操作前必须确认磁盘上没有重要数据并做好备份。生产环境更推荐用 swap 文件,简单可控、易于回滚。
性能影响:什么时候是救命,什么时候是灾难
Swap 的代价就是磁盘速度远低于内存。影响程度取决于 Swap 所在设备:
| Swap 设备 | 随机读写延迟量级 | 换页体验 |
|---|---|---|
| NVMe SSD | 几十到上百微秒 | 相对可用,缓存仍能感知 |
| SATA SSD | 数百微秒 | 可接受,但高频交换会明显变慢 |
| 机械 HDD | 数毫秒到十几毫秒 | 灾难级,一次换页卡成幻灯片 |
| 网络存储(NFS/云盘) | 视网络 | 最差,抖动大,不推荐做 Swap |
| zram(内存压缩) | 微秒级 + 压缩 CPU 开销 | 好,但吃 CPU |
机械盘做 Swap 是重灾区:一次随机读要花十几毫秒,如果是并发访问,请求排队后延迟飙升,整台机器像卡死一样。老服务器上常见的"负载不高但特别卡",往往就是 Swap 在机械盘上疯狂换页。
SSD 做 Swap 要关心磨损:Swap 的写放大很高,频繁换页会显著消耗 SSD 寿命。企业级 SSD 有高耐久度和掉电保护,问题不大;消费级 SSD 长期高频 Swap 会加速老化。同时 Swap 应放在性能最好、写寿命足够的设备上,别放在已经很繁忙的系统盘上。
判断是否正在被 Swap 拖累,看这三个指标:
free -h # Swap used 是否持续增长
vmstat 1 5 # 看 si/so 两列(每秒换入/换出 KB)
sar -W 1 5 # sysstat 提供的换页统计
vmstat 里 si(swap in)和 so(swap out)持续非零(比如长期几百以上),说明正在频繁换页,性能必然受损。偶尔几十是正常的。so 非常高时,往往是内存压力已经很大了。
该用和不该用 Swap 的场景
| 场景 | 建议 | 理由 |
|---|---|---|
| 通用 Web / 应用服务器 | 配少量(2-4G),swappiness 中等 | 防突发、兜底 OOM |
| 数据库(MySQL / PostgreSQL) | 配少量或按官方建议,swappiness 调低(1-10) | 换页会让查询延迟剧烈抖动 |
| Redis / 内存数据库 | 基本不用 Swap,或极低 swappiness | 依赖全部数据在内存,换页等于灾难 |
| 大内存计算节点(>64G) | 可不配或配很小 | 内存充裕,很少用到 |
| 容器宿主 / Kubernetes 节点 | 默认不用 Swap(kubelet 默认要求关闭) | 内存限制和调度依赖精确内存统计 |
| 内存极小的小机器(< 2G) | 配 2 倍内存 | 没有 Swap 会频繁 OOM |
| 机械盘老服务器 | 谨慎,宁可加内存 | 磁盘 Swap 性能极差 |
Kubernetes 节点特别注意:kubelet 默认要求关闭 Swap,因为内存调度依赖准确的内存统计。较新版本支持 Swap 但有额外配置要求。做容器平台时按集群规范来,别自作主张开 Swap。
常见问题
swappiness=0 是不是就关闭 Swap 了?
不是。它只是把内核换出的意愿降到最低,内存真正不足时仍会换出,因为内核要在"使用 Swap"和"触发 OOM"之间做选择。要真正禁用是 sudo swapoff -a,但那样内存紧张时会直接 OOM。
fallocate 建的 swap 文件起不来怎么办?
报 Invalid argument 多半是文件有空洞,底层文件系统不支持 fallocate 或生成了稀疏文件。改用 dd if=/dev/zero of=/swapfile bs=1M count=4096 重建,再 mkswap 即可。
云服务器上还需要自己配 Swap 吗?
主流云厂商的镜像通常默认已配好 Swap(多为 swap 文件),可以先 swapon --show 确认。如果没有且内存偏小,建议手动加一个 2-4G 的 swap 文件做缓冲。如果内存很充裕、业务对延迟敏感,也可以不加。
怎么知道现在有没有在用 Swap?
看 free -h 的 Swap used 和 vmstat 的 si/so。used 不为零说明有页面在 Swap 上;si/so 持续非零才说明在频繁换入换出,才会明显影响性能。另外 cat /proc/PID/status 里的 VmSwap 能看到某进程被换出了多少。
Swap 配得越大越好吗?
不是。Swap 太大会掩盖内存不足的问题,让系统在性能已经严重下降时还在硬撑,而不是尽早暴露。合理做法是配一个够缓冲的大小,把 swappiness 调低,让它在正常负载下根本不参与,只在突发或真紧张时兜底。
总结
- Swap 是磁盘上的缓冲空间,不是内存的延伸;它的价值在于防 OOM 和缓冲冷数据,不在于"扩容内存"。
- 现代大内存服务器的趋势是少配或不配 Swap,内存小的机器配 2 倍;通用建议是 2G-8G 做保命垫,具体看场景。
vm.swappiness默认 60,数据库等延迟敏感服务调低到 1-10,但别误以为 0 就是禁用;修改要用/etc/sysctl.d/持久化。- 建 swap 文件优先用
fallocate,遇到报错改dd;务必chmod 600、mkswap、写 fstab 并校验,回滚就是swapoff加删除。 - 机械盘做 Swap 是性能灾难,SSD 要关心寿命,zram 是内存换压缩的替代;用
vmstat的si/so判断是否正被拖累,别只看Swap used。 - 配了 Swap 不代表内存就够了,CPU、内存、磁盘要综合看;频繁交换说明该加内存或优化程序,而不是加大 Swap。
企业QQ咨询




