
1. 从一次线上告警说起swap 到底在什么情况下会咬人凌晨两点监控面板上一条内存使用率的曲线突然拉满紧接着几台业务节点的响应时间从几十毫秒飙到两秒以上。登录机器一看free -h显示物理内存还剩一点但 swap 已经被吃掉了一大半si/soswap in/out的数值在vmstat里持续跳动。这不是内存不够用那么简单而是系统在疯狂地把内存页换进换出磁盘 IO 被拖垮整台机器像陷进泥潭一样。很多人对 swap 的态度是两个极端要么觉得它是救命稻草内存不够就靠它扛要么觉得它纯粹是性能杀手恨不得第一时间swapoff关掉。这两种想法都太粗暴了。swap 本质上是操作系统内存管理的一层缓冲它解决的是物理内存瞬时不够和长期不活跃的内存页占着茅坑这两类问题。用得好它是安全垫用不好它就是性能黑洞。这篇内容我打算把 Linux swap 从概念、查看、创建、启停到调优这一整条链路讲透重点放在启停操作上因为这是日常运维里最容易被误操作、也最容易踩坑的环节。适合谁看刚接触 Linux 运维的同学可以当作一份可复现的操作手册有一定经验的工程师可以重点看调优参数和排查思路那几节里面有不少我在实际环境里踩出来的经验。核心关键词就三个swap、启停操作、swappiness后面会反复围绕它们展开。先说一个基本认知swap 不是内存的替代品而是内存的延伸。物理内存是内存条速度快但容量有限swap 是磁盘上的一块空间速度慢但容量可以很大。系统把暂时不用的内存页挪到 swap 里等需要时再换回来。这个挪和换的过程就是 swap in/out代价是磁盘 IO。理解了这一点后面所有的调优和启停决策就都有了依据。2. swap 的核心机制与方案选型拆解2.1 swap 空间到底解决了什么问题要理解 swap 的价值得先理解 Linux 的内存管理逻辑。Linux 采用的是虚拟内存机制每个进程看到的是连续的虚拟地址空间实际映射到物理内存页。当物理内存紧张时内核的内存回收机制会启动它会优先回收那些干净的页比如文件缓存直接丢弃即可然后是脏页需要写回磁盘最后才是把匿名页进程堆栈这类没有文件背景的内存换出到 swap。这里有个关键点匿名页只能换到 swap。如果没有 swap内核在物理内存耗尽时只能触发 OOM Killer直接杀掉进程。所以 swap 的第一层价值是防止进程被误杀给系统一个缓冲的余地。第二层价值是让不活跃的内存页腾位置比如一个常驻进程启动后加载了一堆代码之后长期不用这些页就可以被换出去把宝贵的物理内存让给真正活跃的业务。但代价也很明显。磁盘的随机读写速度比内存慢好几个数量级机械盘更是慢得离谱。一旦系统频繁发生 swap in/out也就是所谓的抖动thrashing性能会断崖式下跌。所以 swap 的使用原则是能不用就不用但不能没有。它是一个安全网而不是日常跑道。2.2 swap 分区还是 swap 文件怎么选创建 swap 有两种方式swap 分区和swap 文件。这两种方式在功能上完全等价内核处理起来没有区别但在实际使用中各有取舍。swap 分区是在磁盘分区阶段就划出来的一块独立分区类型标记为82Linux swap。它的优势是性能略好因为分区是连续的磁盘块没有文件系统的开销劣势是扩容麻烦一旦划分好想调整大小就得动分区表风险高、操作重。传统物理机和早期服务器普遍用这种方式。swap 文件是文件系统里的一个普通文件用dd或fallocate创建然后格式化成 swap。它的优势是灵活想加就加想删就删扩容只需要再建一个文件或者调整现有文件大小劣势是在某些老文件系统比如 ext3上会有碎片问题性能略逊于分区。现在主流的云主机、容器环境基本都用 swap 文件因为弹性好。我的建议很直接新环境一律用 swap 文件。除非你有极端的性能要求否则那点性能差异在日常业务里根本感知不到而灵活性带来的运维便利是实打实的。下面这张表把两者的差异列清楚对比维度swap 分区swap 文件性能略优连续磁盘块略逊取决于文件系统碎片扩容困难需动分区表简单新建或调整文件即可缩容困难简单swapoff 后删除适用场景传统物理机、固定配置云主机、容器、弹性环境操作风险高低2.3 swappiness 参数背后的取舍逻辑vm.swappiness是 swap 调优里最核心的参数取值范围 0 到 100默认值通常是 60。它控制的是内核倾向于把匿名页换出到 swap 的程度注意它不是一个开关而是一个权重。这个参数的工作机制经常被误解。很多人以为设成 0 就完全不使用 swap其实不是。swappiness0只是说内核在回收内存时会尽量避免使用 swap但在物理内存真正耗尽、且没有其他可回收页的极端情况下仍然会动用 swap。要完全禁用 swap得用swapoff这是两码事。那这个值怎么定我的经验是这样数据库服务器MySQL、PostgreSQL 这类设成1到10。数据库对内存延迟极其敏感一旦发生 swap查询性能会剧烈波动。低 swappiness 能让内核尽量保留数据在物理内存里。通用应用服务器设成10到30。既保留一定的缓冲能力又不至于频繁换出。桌面环境或内存极度充裕的机器可以设成60甚至更高让系统自由调度。容器宿主机要特别小心容器内的进程看到的 swappiness 可能受 cgroup 限制宿主机层面的设置不一定直接生效。提示调整 swappiness 是运行时生效的sysctl vm.swappiness10立即起作用但要持久化必须写进/etc/sysctl.conf或/etc/sysctl.d/下的配置文件否则重启就丢。3. 查看与评估动手前先摸清现状3.1 用 free 和 swapon 快速摸底动手操作前第一步永远是看清楚现状。最常用的命令是freefree -h输出大概长这样total used free shared buff/cache available Mem: 15Gi 9.2Gi 1.1Gi 320Mi 5.1Gi 5.6Gi Swap: 4.0Gi 1.3Gi 2.7Gi这里要重点看几个数Swap行的total是 swap 总大小used是已用free是剩余。但光看这个不够还得结合available那一列——它才是应用真正还能用多少内存的估算值包含了可回收的 buff/cache。另一个命令是swapon它列出当前激活的 swap 设备swapon --show输出会显示每个 swap 设备的名称、类型、大小和优先级NAME TYPE SIZE USED PRIO /swapfile file 4G 1.3G -2PRIO是优先级数值越大越优先使用。多个 swap 设备时内核会先填满高优先级的再往低优先级写。这个特性在需要临时扩容时很有用。3.2 用 vmstat 判断是否真的在抖动free只能告诉你 swap 用了多少但用了多少不等于正在频繁换。一个进程启动时被换出去、之后一直没动swap 占用高但系统很健康。真正要命的是持续的 swap in/out。这时候要看vmstatvmstat 1 5关注siswap in从 swap 读回内存和soswap out从内存写到 swap两列单位是 KB/s。如果这两个值长期非零尤其是持续几百上千说明系统正在频繁换页性能已经受影响了。如果只是偶尔跳一下那属于正常波动。我一般会连续观察几分钟配合top或pidstat看是哪个进程在制造内存压力。有时候是某个进程内存泄漏有时候是缓存策略不合理找到根因比盲目调 swap 更重要。3.3 评估当前 swap 配置是否合理判断 swap 大小是否合适没有绝对标准但有几个参考维度。传统经验法则是物理内存小于 2G 时swap 设为内存的 2 倍2G 到 8G 之间设为等于内存大于 8G 时设为 4G 到 8G。但这套规则来自机械盘时代现在参考价值有限。更实用的判断方法是看峰值内存需求。如果业务在高峰期物理内存使用率长期超过 80%且 swap 使用量也在涨那说明内存确实不够要么加内存要么合理扩大 swap 作为缓冲。如果物理内存充裕、swap 几乎不用那 swap 大小只要够兜底就行4G 到 8G 足矣。注意swap 不是越大越好。过大的 swap 会让内核更放心地换出内存反而可能拖慢系统。它的定位是安全垫不是主力。4. 创建与启用 swap 的完整实操4.1 用 fallocate 或 dd 创建 swap 文件创建 swap 文件有两种主流方式。fallocate速度快直接分配磁盘块dd慢一些但兼容性更好在某些文件系统上更可靠。用fallocate创建一个 4G 的 swap 文件sudo fallocate -l 4G /swapfile如果fallocate报错或者创建出来的文件有问题某些文件系统不支持改用ddsudo dd if/dev/zero of/swapfile bs1M count4096这里的bs1M count4096就是 1M 乘以 4096等于 4G。bs是块大小count是块数量两者相乘就是文件大小。这个计算过程要心里有数别拍脑袋写数字。创建完先确认大小ls -lh /swapfile4.2 设置权限与格式化swap 文件里可能包含内存中的敏感数据所以权限必须收紧只允许 root 读写sudo chmod 600 /swapfile这一步千万别省。权限太松的话普通用户能读到 swap 文件内容等于能窥探其他进程的内存数据这是实打实的安全隐患。然后把它格式化成 swapsudo mkswap /swapfile成功的话会输出类似Setting up swapspace version 1, size 4 GiB的信息。如果提示文件正在使用或者大小异常回头检查上一步。4.3 启用 swap 并验证格式化完成后启用它sudo swapon /swapfile再用swapon --show或free -h验证是否生效。如果Swap行的 total 增加了说明启用成功。到这里 swap 只是临时生效重启后会丢失。要持久化得写进/etc/fstabecho /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab这行的含义是设备是/swapfile挂载点写noneswap 没有挂载点文件系统类型是swap挂载选项是sw表示 swap后面两个0分别是 dump 和 fsck 的选项swap 不需要它们。提示改完/etc/fstab后强烈建议用sudo mount -a测试一下确认没有语法错误。fstab 写错会导致系统启动失败这个坑我见过太多次。4.4 多 swap 设备的优先级配置有时候需要临时加一块 swap 应急或者想把 SSD 和机械盘上的 swap 分开管理。这时候可以用优先级。在/etc/fstab里加pri选项/swapfile1 none swap sw,pri10 0 0 /swapfile2 none swap sw,pri5 0 0pri数值越大优先级越高内核会优先使用高优先级的 swap。这样可以把快的设备比如 SSD设高优先级慢的设低优先级兼顾性能和容量。5. 停用 swap 的正确姿势与风险控制5.1 swapoff 的执行逻辑与内存回流停用 swap 用swapoff命令sudo swapoff /swapfile或者停用全部sudo swapoff -a这个命令做的事情是把 swap 里的所有数据页读回物理内存然后标记该 swap 空间为不可用。注意是读回内存不是丢弃。所以这里有个硬性前提——物理内存必须能装下 swap 里的所有数据。如果 swap 用了 3G而物理内存只剩 1G 可用swapoff会失败报Cannot allocate memory之类的错误。这时候强行停用是不可能的因为数据没地方放。解决办法要么先释放内存停掉一些进程要么加内存要么就别停。5.2 停用前的内存余量评估停用 swap 前一定要算一笔账。用free -h看available那一列这是物理内存里真正可用的部分。再对比 swap 的used。只有当available明显大于 swap 的used时swapoff才有成功的把握。举个具体例子物理内存 16Gavailable 显示 6Gswap used 是 2G。这种情况下swapoff大概率能成功因为 6G 的可用空间装得下 2G 的 swap 数据。但如果 available 只有 1.5Gswap used 是 2G那就悬了很可能中途失败。我一般会留出至少 1.5 倍的余量也就是 available 要大于 swap used 的 1.5 倍给系统运行和其他进程留点空间。这个余量不是死规定但保守一点总没错。5.3 停用 swap 的典型场景什么时候需要停用 swap我总结了几类性能调优数据库服务器发现 swap 使用导致延迟抖动决定彻底禁用 swap强制所有数据留在内存。更换 swap 设备要把 swap 从机械盘迁到 SSD先停旧的再启新的。缩容swap 文件太大占磁盘想缩小或删除。排查问题怀疑 swap 引发性能问题临时停用做对比测试。但要注意停用 swap 不等于解决问题。如果物理内存本来就不够停用 swap 只会让 OOM Killer 更早动手。停用前想清楚内存到底够不够不够的话停 swap 是治标不治本。5.4 永久禁用 swap 的完整步骤如果确定要永久禁用步骤要完整别只做一半临时停用sudo swapoff -a从/etc/fstab里删掉或注释掉 swap 那一行如果不再需要 swap 文件删除它sudo rm /swapfile验证重启后free -h里 Swap 行应该全是 0只做第 1 步的话重启后 swap 又回来了因为 fstab 里还写着。这个顺序不能乱先停用再改配置避免中间状态出问题。注意有些云主机的 swap 是由 cloud-init 或系统服务动态管理的光改 fstab 可能不够还得检查相关服务配置。这个因环境而异遇到问题要顺着swapon --show的结果去追来源。6. 调优参数与常见问题排查实录6.1 swappiness 与 vfs_cache_pressure 的配合除了 swappiness还有一个相关参数vm.vfs_cache_pressure默认值 100。它控制内核回收用于目录和 inode 缓存的倾向。值越高越倾向于回收这些缓存值越低越倾向于保留。这两个参数经常配合调整。比如文件服务器场景希望保留大量目录缓存加速查找可以把vfs_cache_pressure调低到 50 左右同时 swappiness 也调低。而内存紧张的通用服务器可以保持默认或略调高。调整方式sudo sysctl vm.swappiness10 sudo sysctl vm.vfs_cache_pressure50持久化同样写进/etc/sysctl.d/99-swap.conf这类文件里。我习惯单独建一个配置文件而不是直接改/etc/sysctl.conf这样便于管理和回溯。6.2 swap 相关常见问题速查表下面这张表是我这些年遇到过的 swap 相关问题汇总按现象、可能原因、排查方向整理现象可能原因排查方向swapoff 报 Cannot allocate memory物理内存装不下 swap 数据看 free 的 available释放内存或加内存系统响应变慢si/so 持续高内存不足导致频繁换页vmstat 看 si/sopidstat 定位进程swap 使用率居高不下但不卡不活跃页被换出属正常观察 si/so 是否长期非零重启后 swap 消失fstab 没配置或写错检查 /etc/fstab 和 swapon --showswap 文件创建后大小不对fallocate 不被文件系统支持改用 dd 创建多 swap 设备使用不均优先级配置问题检查 pri 选项容器内 swap 行为异常cgroup 内存限制检查容器内存配置和宿主机 swap6.3 我踩过的几个坑第一个坑是在内存紧张时贸然 swapoff。有次一台机器 swap 用了 2G物理内存 available 只有 1.8G我想着差不多就执行了swapoff结果命令卡住系统直接进入假死状态最后只能硬重启。教训就是余量一定要留够别卡着临界值操作。第二个坑是fstab 写错导致启动失败。早期有次手抖把 swap 那行的选项写错了重启后系统进不了正常模式只能进救援模式改回来。从那以后我改 fstab 必做mount -a测试而且改之前先备份。第三个坑是以为 swappiness0 就是禁用 swap。这个误解害我在一次性能测试里得出错误结论后来才搞清楚 0 只是尽量不用真要禁用得swapoff。这两个概念一定要分清。第四个坑是swap 文件权限没设。有次图快创建完直接mkswap就启用了忘了chmod 600。虽然没出安全事故但被安全扫描工具报了出来属于低级失误。6.4 性能敏感场景的 swap 策略对于数据库、实时计算这类性能敏感的场景我的策略是物理内存给足swap 保留但设低优先级。具体做法是保留一个较小的 swap比如 4G作为兜底把 swappiness 设成 1 到 10让内核几乎不主动换出。这样既避免了 OOM 直接杀进程又不会因为频繁换页拖慢性能。如果内存实在紧张宁可加内存也不要指望 swap 扛。swap 的定位始终是安全网不是扩容方案。把 swap 当内存用性能一定会教你做人。7. 写在最后的一点个人体会swap 这个东西说简单也简单几条命令就能搞定说复杂也复杂参数、优先级、启停时机、和内存的配合每一环都有讲究。我自己的习惯是新机器先规划好 swap用文件方式大小按业务峰值内存的 20% 到 50% 预留swappiness 按业务类型调然后定期用 vmstat 观察 si/so。这套流程跑下来基本不会出大问题。最后分享一个小技巧如果你不确定某个 swappiness 值是否合适可以先用sysctl临时改跑一段时间观察业务指标确认没问题再持久化。这样比直接改配置文件稳妥得多改错了重启就恢复不会留下隐患。swap 的启停操作本身不难难的是判断什么时候该动、动多少这个只能靠对业务的了解和持续的观察积累。