ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux Swap 文件从创建到调优:原理、实操与排障全指南

Linux Swap 文件从创建到调优:原理、实操与排障全指南 1. Swap 到底是什么为什么 Linux 离不开它先说个直白的结论不管你是刚装好第一台 Linux 虚拟机的新手还是维护着几十台生产服务器的运维老手Swap 都是你迟早要正面打交道的东西。很多人对 Swap 的第一印象是内存不够时的备胎这没错但备胎的用法和保养方式远比大多数人想的要讲究。用一句话说清楚Swap 是磁盘上的一块空间当物理内存RAM不够用时内核会把暂时不用的内存页挪到磁盘上腾出物理内存给更急需的进程。这个过程叫换出swap out等需要时再读回来叫换入swap in。听起来很简单对吧但这里有个非常关键的认知Swap 不是内存满了才有用的东西。内核有一套复杂的内存回收机制即使在内存还够用的情况下它也会主动把一些页面换出去——比如长时间不访问的文件缓存会被回收不活跃的匿名内存页也会被换出。这就是为什么你经常看到明明内存还剩好几个 GSwap 却已经有使用量了。这是内核在提前做准备不是系统出故障了。那 Swap 到底解决什么问题掰开揉碎说三点第一防止 OOM 杀人。Linux 内核在内存彻底耗尽时会启动 OOM Killer 按分数干掉进程。没有 Swap 的情况下OOM Killer 触发得极其频繁而且杀谁不完全由你说了算——它按 oom_score 来选有时候杀的是你的 nginx有时候是数据库甚至可能是 sshd。有了 Swap系统能多撑一阵给你留出排查和处理的时间。第二让内存的热点数据更有效率。听起来反直觉但适度的 Swap 反而能提升性能。因为磁盘上的冷数据占着内存会导致热数据正在高频访问的页面没有足够的缓存空间。把冷数据换出去热数据能利用更多物理内存整体吞吐反而更高。第三扛住突发内存峰值。业务流量突然涨了、某个进程一次性申请了大量内存、或者你写了段有内存泄漏的代码——在扩容机器之前Swap 是唯一的缓冲垫。我在生产环境上见过好几回半夜告警内存使用率飙到 95%全靠 Swap 撑住等早上业务低谷再把问题从容处理掉。顺带纠正一个很常见的误区很多人觉得 Swap 是慢的代名词能不开就不开。这个说法对现代服务器来说已经过时了。磁盘速度的确比内存慢几个数量级但如果内核的换页策略调得合适后面会详细讲 swappiness 参数Swap 绝大多数情况下只是兜底不会成为性能瓶颈。反而是裸奔没 Swap 的机器OOM 杀进程给业务带来的影响远比 Swap 那点 I/O 损耗严重得多。另外在说明创建方法之前必须把 Swap 文件swap file和 Swap 分区swap partition的区别讲清楚因为这也是后来者特别容易混淆的地方对比项Swap 分区Swap 文件灵活性创建后扩容困难需要重新分区随时可以增加或删除文件部署成本安装系统时就要规划系统装完随时都能加性能连续磁盘位置略优经过文件系统层稍有损耗现代 SSD 下差距极小适用场景传统服务器、对性能极致敏感虚拟机、云主机、容器宿主机、快速应急我的建议很明确新环境一律用 Swap 文件。原因不复杂——云主机和虚拟机里你很难提前预知业务未来要吃多少内存Swap 文件想加就加、想减就减改起来一条命令的事。Swap 分区挪起来那叫一个痛苦。而且现在 SSD 普及了文件型 Swap 和分区型 Swap 的性能差距基本可以忽略不计。2. 动手前先盘盘家底检查现状与选型思路很多教程上来就让你敲命令创建这是不对的。正规流程应该先搞清楚三件事现在系统里有没有 Swap 了有多少内存多大、什么用途先看现状。三条命令基本就够用# 查看当前 Swap 总量和已用量 free -h # 查看当前启用的 Swap 设备和文件列表 swapon --show # 查看更多细节包括优先级、类型 cat /proc/swaps输出里如果 Swap 一栏全是 0 或者直接没有说明系统还没配置 Swap。有些云厂商的默认镜像比如某些轻量服务器就把 Swap 砍掉了理由是云硬盘 I/O 贵这部分用户往往等内存告警了才想起来补。看完现状再看内存大小。Swap 该配多大网上说法五花八门有说等于内存的有说内存两倍的还有说 4G 以下内存必须双倍的——这些老黄历主要来自早期内存极贵的年代。现在靠谱的选型逻辑是这样的内存小于 2G 的轻量机器Swap 给到内存的 1~2 倍比如 1G 内存配 2G Swap减少 OOM 概率内存 4G~16G 的通用服务器Swap 给 2G~8G但要结合业务看。数据库类应用通常希望尽量不用 Swap给个 2G 兜底即可跑 Java、Node 这类吃内存的应用可以放宽到 4G~8G内存 32G 以上的大内存机器Swap 给 4G~8G 就够。内存都这么大了Swap 的意义主要是防 OOM 兜底而不是真的指望它撑容量休眠hibernation场景另算Swap 必须大于等于内存但服务器基本不碰这个这里不展开还有个关键考量你的磁盘是什么类型。如果系统盘是机械盘Swap 性能会很难看但总比没有强。如果是 NVMe SSDSwap 文件的性能损失完全可以接受。如果用的是网络存储比如某些云盘的系统盘是挂载的就要慎重了——网络 I/O 延迟高频繁换页会导致系统卡成幻灯片。这种情况我建议把 Swap 文件建在本地盘上哪怕小一点。选完大小还有两个决策点第一个Swap 文件放哪个目录。Linux 对 Swap 文件的位置没有要求但我建议放在根目录下直接取名/swapfile原因只有一个根文件系统是系统启动时最先挂载的如果放在/home或/data这类后挂载的独立分区上开机挂载时设备还没就绪Swap 就起不来需要在 rc 脚本里做额外处理。放根目录能少踩一个大坑。第二个一个 Swap 还是多个 Swap。完全可以有多个系统允许你同时启用好几个 Swap 文件和分区。实际场景里有人会为不同业务配置不同优先级的 Swap但这属于高级玩法一般家用和普通服务器一个/swapfile就够了后续不够再加第二个文件直接在/etc/fstab里再写一行就行。顺带说一句检查完现状如果发现已经存在 Swap 分区但是太小也不用急着删分区重建——直接加一个 Swap 文件顶上再通过优先级参数让新文件先被使用就能无损完成扩容这个技巧后面的章节会讲到。3. 从零创建 Swap 文件完整实操流程现在进入正题。以下步骤我在 Ubuntu 22.04、Debian 12、CentOS 7/8/9 上都实测过命令通用唯一区别是包管理器但创建 Swap 全程也不涉及装包。3.1 创建指定大小的空白文件两种主流方式fallocate和dd。# 方式一fallocate推荐快 sudo fallocate -l 4G /swapfile # 方式二dd慢但兼容性最稳 sudo dd if/dev/zero of/swapfile bs1M count4096 statusprogress两者区别在哪fallocate是直接在文件系统上分配空间瞬间完成本质上是给文件打了预定标记并没有真正往磁盘写内容。dd则是老老实实把全零数据写进磁盘4G 的文件在机械盘上要等几分钟SSD 上也就十几秒。我为什么大部分场景推荐fallocate快是一方面另一个原因是现代内核4.3 以后配合 ext4、XFS 都没有问题。但有一点必须提醒如果你用的文件系统比较特殊比如 ZFS 或者某些网络文件系统fallocate出来的 Swap 文件可能会在mkswap时报错这时候老老实实用dd不要为省那几秒折腾。顺带讲个参数细节bs1M count4096是 4Gcount乘以bs就是最终大小。想要 8G 就count8192算不清楚就直接bs1G count4效果一样。statusprogress是给 dd 加进度条不然大文件写入时屏幕一直静止容易让人以为卡死了。3.2 修改权限这一步不能省sudo chmod 600 /swapfile这条命令的意义很多人忽略。Swap 文件里保存的是内存页的快照——里面可能有密码、密钥、临时明文数据这些内容的敏感性不亚于系统上的任何文件。如果不把权限收紧到 600仅 root 可读写系统还会在启动时给出安全警告甚至直接拒绝swapon。实际上mkswap命令会对文件权限做检查权限不对就拒绝执行。所以这条命令顺序上放在mkswap之前别搞反了。3.3 格式化为 Swap 文件系统sudo mkswap /swapfile输出会告诉你做了个 swap 文件系统并给出一串 UUID。这个过程叫格式化只不过格式化的目标是 swap 类型而非 ext4。注意看输出如果提示insecure permissions之类的话说明第 3.2 步的权限没设对回头改掉再跑一次。3.4 启用 Swap 文件sudo swapon /swapfile跑完再用swapon --show看一眼能看到路径、类型file、大小这就说明 Swap 已经激活了。此刻它已经生效但只是临时生效——重启之后就没了所以下一步必做。3.5 写入 fstab实现开机自动挂载这一步是新手最容易翻车的环节多给点细节。编辑/etc/fstabsudo vim /etc/fstab在文件末尾加一行/swapfile none swap sw 0 0字段含义拆开讲/swapfile是设备或文件路径none是挂载点Swap 没有挂载点所以写 noneswap是文件系统类型sw是挂载选项表示以 swap 方式启用0 0分别是 dump 备份开关和 fsck 检查顺序Swap 不需要参与这些全填 0。注意这里有个极易踩的坑fstab 如果写错了系统重启时会直接卡在启动环节甚至进入紧急模式emergency mode干等着你去修复。所以在重启之前务必先验证这一行配置有没有问题# 卸载再启用验证 fstab 写法没问题 sudo swapoff /swapfile sudo swapon -aswapon -a会按 fstab 里所有配置去启用 Swap。如果不报错说明配置没问题。这时候再重启就安心了。我见过太多人在 fstab 里写错路径结果第二天上班发现服务器进不去这个验证习惯可以帮你省一次事故。3.6 一套完整的命令串把上面这些串起来一条条执行就是完整流程# 1. 创建 4G 的 swap 文件 sudo fallocate -l 4G /swapfile # 2. 收紧权限 sudo chmod 600 /swapfile # 3. 格式化为 swap sudo mkswap /swapfile # 4. 启用 sudo swapon /swapfile # 5. 写入开机自启 echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab # 6. 验证 free -h swapon --show到这一步一个基本可用的 Swap 文件就上线了。但是仅仅能用离好用还差得远接下来才是重头戏——调优。4. 调优 Swap让内核按你的思路工作Swap 创建完默认参数其实偏保守不一定适合你的业务。这一节讲几个核心参数每个都会影响系统的内存回收行为和 Swap 使用倾向。4.1 核心参数 swappiness控制多积极地使用 Swap这是讨论度最高的一个参数全名vm.swappiness作用范围 0~100新版内核放宽到 200默认值一般是 60。它的含义是内核在回收内存时倾向于换出匿名内存页进程占用的内存而不是回收文件缓存page cache的程度。把这个参数理解成换页的积极性就通了取值越小内核越不愿意把进程内存换出去越倾向于回收文件缓存Swap 用量就少取值越大内核越积极地把冷内存换出去Swap 使用量就高典型配置方案# 查看当前值 cat /proc/sys/vm/swappiness # 临时修改重启失效 sudo sysctl vm.swappiness10 # 永久修改 echo vm.swappiness 10 | sudo tee -a /etc/sysctl.conf我的经验值台式机和开发机设 10~30交互响应优先别让 Swap 频繁介入拖慢操作。内存紧张的服务器设 10~20保命优先但不能让它把磁盘 I/O 打满。数据库服务器设 1~10数据库对延迟极度敏感宁可让 OOM Killer 有概率介入也不想让查询因为换页变慢。完全不建议设成 0——0 表示尽量不用 Swap在某些内核版本上甚至会因为内存回收路径的变化导致 oom 概率上升得不偿失。有个特殊情况说明一下如果你用的是什么桌面发行版默认 60 在日常浏览时可能你会发现 Swap 用了不少但内存还剩很多这很正常内核在预加载。按上面的建议调低即可。4.2 vfs_cache_pressure控制目录和 inode 缓存的回收力度这个参数知道的人少但实际价值不小。全名vm.vfs_cache_pressure默认 100范围 0~1000 左右。它的作用控制系统回收 VFS 缓存目录项 dentry 和 inode 缓存的倾向。值越大内核越积极回收这类缓存给文件读写让路值越小目录缓存保留越久访问大量文件时命中率更高。做文件服务器、编译构建机这类场景可以调到 50~80保留更多的目录项缓存能明显减少大量小文件操作的耗时。做数据库服务器保持 100 或略高一点就行。除非你对内核内存管理非常熟否则不建议低于 50太低会让匿名内存回收压力变大反而引发性能问题。4.3 给 Swap 文件排优先级多个 Swap 时谁先用如果系统里有多个 Swap 设备或文件pri字段决定使用顺序。值越大优先级越高内核会优先从高优先级 Swap 开始换页。建新 Swap 文件时用-p参数指定# 给 /swapfile 设置优先级 100 sudo swapon -p 100 /swapfile # 也可以在 fstab 里写 /swapfile none swap sw,pri100 0 0实际场景举例你有个大内存机器默认 Swap 分区性能较差后来你在 SSD 上建了个 Swap 文件。把 SSD 上的新文件优先级设高比如 100老的慢 Swap 设低比如 10内核就会先把页面换到快的 SSD Swap 上只有快 Swap 满了才落慢 Swap。相当于给系统配了一个分级存储这个技巧在做性能优化时非常好用。4.4 调优不是改完就完事要配合监控验证参数改完必须验证效果不然就是在凭感觉做优化。验证方式后面第 5 节会详细讲监控这里先说一个判断逻辑调低 swappiness 后如果发现 Swap 使用量长期为零同时内存使用率持续逼近 100%说明参数调得过低了系统已经放弃使用 Swap 开始裸奔OOM 风险反而升高。合理的状态是Swap 有少量使用内存保持在 70%~90% 的健康区间磁盘 I/O 没有异常波动。另外调优参数只在运行时生效重启后会按/etc/sysctl.conf里的配置恢复。修改完 sysctl.conf 想立即生效不重启用sudo sysctl --system我自己改参数的习惯是一次只改一个参数配合监控观察一到两天再动下一个。同时改好几个参数出问题根本没法定位是哪个导致的。这不是学究气这是排障的基本素养。5. 监控 Swap 状态别等系统卡死了才想起来看Swap 是个平时想不起出问题要人命的东西所以监控手段必须提前掌握。日常运维我用的工具和方法如下。5.1 基础命令三板斧第一板斧是free -h看整体内存和 Swap 的用量free -h输出里Swap那行的used和avail要重点盯。如果used长期保持在 80% 以上说明内存压力很大要考虑扩容。第二板斧是swapon --show看具体是哪个 Swap 在被使用以及它的优先级第三板斧是vmstat看换页的实际发生频率vmstat 1 5重点关注siswap in和soswap out两列。这两列单位是 KB/s正常情况下应该非常小甚至为 0。如果si和so持续有较大的数值比如几百 KB/s 以上说明系统正在高频地换入换出这种状态叫 thrashing抖动基本上等于系统在用磁盘当内存性能会断崖式下跌。出现 thrashing 的正确姿势不是改参数而是赶紧加内存或者排查内存泄漏。要看得更细配合sar记录历史数据# 每 10 分钟采样一次并保存 sar -S 60 10-S是专门看 Swap 统计的选项。在有历史数据的服务器上还能回溯前几天的 Swap 使用趋势对定位内存是不是慢慢泄漏了这类慢性问题特别有用。5.2 判定 Swap 是否有问题的三个信号根据我的经验Swap 出问题通常有三个信号按出现频率排一是系统响应变慢但 CPU 空闲。CPU 占用不高load average 也不高但操作就是卡。这时候八成是换页 I/O 在作祟跑一下vmstat 1 5就能确认。二是磁盘 I/O 突然异常升高。用iostat看util接近 100%同时 Swap 使用量在涨基本可以断定换页风暴。三是dmesg 日志里频繁出现内存相关的告警dmesg -T | grep -i out of memory\|oom一旦看到 OOM 字样说明系统已经在杀进程了这是最严重的情况。如果 Swap 配得合理OOM 出现的概率会大幅降低。5.3 做一张监控速查表把常用的检查和对应动作整理成一张表方便值守时快速对照观察项健康状态风险状态建议动作Swap 使用率长期 50%持续 80%排查内存占用考虑扩容si/so 换页速率基本为 0持续 500KB/s加内存或定位内存泄漏内存使用率70%~90% 波动长期 98%调整 swappiness 或扩容dmesg OOM 记录无有立即检查最大内存进程磁盘 I/O util平时 50%Swap 高用时接近 100%检查是否有换页风暴这套监控思路不复杂但足够应付绝大多数场景。监控只是手段最终目的是在故障发生前把隐患消掉——我个人的习惯是每周五下午花十分钟扫一遍所有服务器的 Swap 使用趋势成本极低收益很高。6. 常见坑与排障实录这些坑我踩过你别再踩写这一节是因为我实在见过太多人在 Swap 上栽跟头很多坑属于书上不会写出事才后悔。我把最典型的几个整理出来每条都是真实生产环境里遇到过的。6.1 坑一swap 文件被误删但系统还在用这是个非常经典的坑。Swap 文件启用后如果手滑把/swapfile删了系统并不会立刻崩溃进程也还能继续跑——因为内核已经持有该文件的 inode被换出的页面依然可以写入和读取。但这是个定时炸弹等你重启系统swap 文件没了fstab 里的配置也指向一个不存在的文件启动时要么报错要么直接进入 emergency mode。排查方法# 如果 fstab 里配置了 /swapfile 但文件不存在 ls -lh /swapfile # 如果文件还在但系统启动报错可能是文件权限或内容被破坏 sudo mkswap /swapfile修复思路按第 3 节的完整流程重建 swap 文件再swapon -a验证。日常养成习惯别在 Swap 启用状态下去动 swap 文件的目录结构误删过的人都知道这话的分量。6.2 坑二fallocate创建的 swap 文件在某些文件系统上不兼容前面提过一句这里展开讲。在 XFS 上用fallocate没问题在 ext4 上也没问题但在一些特殊文件系统上fallocate创建的文件底层块并未真实分配mkswap执行时可能直接报mkswap: error: swap area needs to be a regular file或者干脆提示没有合适的分区类型。遇到这个情况别纠结删掉文件换dd重来sudo rm /swapfile sudo dd if/dev/zero of/swapfile bs1M count4096 statusprogress sudo chmod 600 /swapfile sudo mkswap /swapfile虽然dd慢但它是纯物理写入任何文件系统上都兼容。记住一个原则求稳用 dd求快用 fallocate出问题先别怀疑系统先怀疑 fallocate。6.3 坑三修改 swappiness 后重启失效这是新手最容易忽略的问题之一。用sysctl vm.swappiness10改的只是运行时值重启后系统会重新加载/etc/sysctl.conf。如果你的配置没写进去重启后一切回到默认值。确认方法# 看配置是否已写入 grep swappiness /etc/sysctl.conf # 立即生效且持久化 echo vm.swappiness 10 | sudo tee -a /etc/sysctl.conf sudo sysctl --system如果发现 /etc/sysctl.conf 里的配置没生效多半是文件里重复定义了同一个参数后面的覆盖了前面的。用sysctl vm.swappiness查看当前实际值和配置值比对即可判断。6.4 坑四服务器上 Swap 不够用不想重启扩容前面说过可以新增一个 swap 文件而不动旧的。假设现有 4G swap 已用完再加一个 4Gsudo fallocate -l 4G /swapfile2 sudo chmod 600 /swapfile2 sudo mkswap /swapfile2 sudo swapon -p 50 /swapfile2 echo /swapfile2 none swap sw,pri50 0 0 | sudo tee -a /etc/fstab这样系统就有了 8G 总 Swap并且新的/swapfile2优先级更高先被使用。全程不用重启不用动原来的文件风险极低。如果哪天觉得不需要第二个了swapoff /swapfile2再删文件、删 fstab 里那一行就干净地卸掉了。6.5 坑五容器和云主机里的特殊注意点在 Docker 容器里直接操作 Swap 的权限通常是受限的容器一般依赖宿主机的内存和 Swap 管理。这时候的排查思路就要切换到宿主机层面先在宿主机上检查再回容器里看业务进程的内存趋势。云主机上还有一个隐藏问题如果你的云厂商默认关闭了 Swap同时系统盘还不是普通的本地盘那创建 Swap 文件后一定要实测读写性能。测法很简单# 少量数据先验证 swap 读写正常 sudo swapon /swapfile free -h如果开启后发现磁盘 I/O 延迟异常高建议直接把 swap 文件建在实例的本地临时盘ephemeral disk上——临时盘没了但性能好和持久性差的特性正好符合 Swap 的定位丢了重建即可。6.6 附一张常见问题速查表现象可能原因解决动作swapon 报权限错误swap 文件权限不是 600sudo chmod 600 /swapfileswapon 报文件格式错误文件不是 swap 文件系统重新sudo mkswap /swapfile重启后 Swap 没启用fstab 缺配置或路径错检查 fstab执行sudo swapon -a内存还剩很多但 Swap 已满内核预换出策略激进调低vm.swappiness系统卡死但 CPU 空闲换页抖动vmstat确认加内存或查泄漏无法删除 swap 文件Swap 还在启用状态先sudo swapoff /swapfile7. 收尾前再讲点实在的我的个人习惯总结写到这里该讲的原理和实操都说完了。最后分享几个我自己的习惯不一定适用于所有环境但都是踩过坑之后沉淀下来的参考价值比前面任何一段都高。习惯一新建服务器第一件事就把 Swap 文件建好。哪怕暂时用不到防患于未然的成本远低于事后救火。数据库、缓存这类服务尤其需要它们一旦被 OOM Killer 干掉恢复的成本可能比加内存还高。习惯二Swap 文件和日志目录不要放同一个磁盘分区。如果系统盘空间本身紧张Swap 文件占着空间日志增长又没有其他地方可去最终两个一起完蛋。有条件的话给 Swap 单独留一个分区或者使用独立磁盘。习惯三每次调完参数都记录当时为什么这么调。比如在服务器上留一个注释规范很好的/etc/sysctl.conf每个参数后面写清楚适用场景和调整日期。你下个月再看这个文件的时候一定是带着感激之情的。习惯四定期查一下 Swap 的使用趋势而不是只看当前值。当前值只能说明此刻的状态趋势才能暴露出内存长期缓慢增长这类问题。配合sar的历史数据往往能比业务方更早发现潜在的内存泄漏。最后说句实在的Swap 这个东西既不是洪水猛兽也不是万能解药。它的价值在于给系统留了一线生机——给运维留出反应时间给业务留出缓冲空间。真正健康的系统Swap 的使用量应该是少量、低频、可控的。如果你的 Swap 使用量长期居高不下别去怪 Swap 参数没调好先回头看看内存是不是根本不够用或者有进程在偷偷吃内存。工具只是工具正视问题本身才是运维的本事。
返回列表