首页 / 资讯中心 / 文章详情

Linux swap文件核心指南:创建、调优、扩容与排查

Linux swap文件核心指南:创建、调优、扩容与排查 ★ FEATURED ARTICLE
1. 扩容前先想清楚swap到底该加多大、加到哪1.1 swap是什么、什么时候才真正需要很多刚接触Linux的朋友容易把swap当作“内存不够时的救命稻草”看到内存告警第一反应就是加swap空间。swap本质上是内存的溢出区域内核把物理内存中暂时不活跃的匿名页anonymous pages写回磁盘上的交换区腾出物理内存给正在活跃的进程用。所以它解决的是“内存短暂被占满、需要缓冲”的问题而不是“物理内存彻底不够”的问题。什么时候确实需要给系统增加swap空间根据我这几年的运维经验大致有几种典型场景。第一服务器长期内存占用超过90%业务有瞬时流量高峰内核的OOM Killer时不时跳出来杀进程这种时候一个swap文件能兜住突发请求。第二本地开发或跑数据分析任务时偶尔要编译大型软件、加载大数据集峰值内存会短暂超过物理内存但又不想立刻去加内存条。第三笔记本或某些工作站要使用休眠功能休眠需要把整个内存镜像写入交换区没有swap就没法休眠。第四有些存量进程存在轻微内存泄漏但短期内无法根治加swap可以延长进程存活时间争取到修复窗口。反过来也要说清楚swap不是万灵丹。如果你的业务负载本身就超出了物理内存承载能力swap只能当止痛药它把内存压力转移成了磁盘I/O压力处理速度比内存慢几个数量级。最常见的结果就是swap用过一段时间后系统整体响应变慢甚至出现持续高iowait。我早年在一台只有2G内存的测试机上跑数据采集任务图省事加了个8G swap结果服务照样被拖垮后来排查才发现是任务本身吃内存太多swap只是把崩溃时间点向后推迟了而已。1.2 容量规划的计算方式和经验值关于swap容量“物理内存的1到2倍”这个老经验在云主机时代依然有参考价值但已经不能无脑套用。现代服务器的物理内存普遍很大如果机器已经有64G内存再按2倍设置128G swap磁盘空间和I/O都会很尴尬。我自己的规划思路是这样的物理内存小于等于2G的机器swap按物理内存的1.5到2倍设置4G到8G的机器按0.5到1倍设置16G到64G的机器预留8G到16G swap作为缓冲就够了超过64G的大内存机器除非有明确的休眠或大内存突发需求否则swap可以控制在16G到32G之间没必要继续往上加。这只是起步参考最终决策还要看free -h里面available内存的实际余量以及业务进程的峰值内存占用。还有两个小点容易被忽略。swap文件会占用磁盘空间你加swap之前必须先看df -h确认目标分区有足够剩余空间我见过有人把swap文件放到根目录结果根分区被写满导致系统异常的案例。磁盘性能也要评估同样大小的swap放在机械盘上和放在SSD/NVMe上完全是两种体验如果数据盘是网络存储还要额外考虑网络I/O稳定性这些都比swap大小本身更影响实际效果。1.3 文件式swap和分区式swap怎么选Linux增加swap空间有两种常见形态swap分区和swap文件。很多人纠结该用哪种我直接给结论绝大多数云服务器和实体机场景建议优先使用swap文件。原因是管理灵活创建、扩容、收缩、移除都不会影响磁盘分区结构对内核来说性能差异并没有传说中那么大。下面用表格做个直观对比对比项swap文件swap分区扩容 / 收缩删除重建即可非常方便需要调整分区表可能影响相邻分区创建方式一条命令完成不需要重启需要分区工具重新划分磁盘碎片问题文件系统碎片存在但现代文件系统影响很小连续空间分配略占优势开机自动挂载在fstab里写一行也需要写fstab或配置设备适用场景临时补内存、快速扩容、虚拟机内操作安装系统时提前规划好的专用分区swap分区在安装系统时如果已经规划好当然可以继续用毕竟它有固定的设备路径稳定性也经过验证。但对于一个已经运行中的系统你想临时增加swap空间最省事、最不容易出错的方案就是创建一个swap文件。后续如果你想迁到独立分区等真正有空窗期再操作也不迟。2. 手把手创建swap文件从检查到持久化的完整操作2.1 先确认当前内存、swap和磁盘状态动手之前先花一分钟看现状。这三个命令是必须跑的free -h查看物理内存和swap的总体情况swapon --show查看当前已有的swap区域类型、路径和优先级df -h查看各分区剩余空间。不要觉得这一步多余我见过太多人跳过检查直接创建swap文件最后要么因为磁盘不够而失败要么发现系统其实已经被swap拖慢了方向完全反了。这里也分享一个判断经验执行free -h后如果available内存还有20%以上系统的主要问题可能不是容量不够而是某个进程占用内存过多这种情况要先去排查进程而不是加swap如果available很低、swap使用率持续攀升再考虑增加swap空间才有意义。把这一步想清楚后面的操作才有价值。2.2 创建交换文件并把权限收紧选定一个空间充足的分区在根目录下创建swap文件。这里要特别提醒一个容易踩的坑swap文件不能放在tmpfs挂载点上典型的就是/dev/shm、/run这类目录。tmpfs本身就是内存文件系统把swap文件放在里面等于把内存数据又“物理”装载到内存里完全失去了交换到磁盘的意义而且系统重启后数据还会消失。创建swap文件的工具常见的有两个一个是fallocate一个是dd。以4G大小的swap文件为例# 方式一fallocate速度很快 fallocate -l 4G /swapfile # 方式二dd逐块写入兼容性最好 dd if/dev/zero of/swapfile bs1M count4096 statusprogressfallocate的优点是快但它在部分文件系统上只会预分配文件逻辑空间的块映射并不一定为文件真正写入数据块结果就是swap文件可能存在“空洞”后面swapon时会报invalid argument。为了避免排错折腾我现在的习惯是创建swap文件一律用dd多等几十秒买一份确定性。文件创建好之后立刻收紧权限chmod 600 /swapfile这一步很有必要。swap文件里装的是内存换出的数据可能包含进程的敏感信息如果权限是644或更高其他普通用户也能读取存在数据泄露风险。另外内核在启用swap时也可能因为文件权限过宽而拒绝工作权限问题在排查时是很常见的隐藏因素。2.3 mkswap与swapon启用把swap文件格式化成交换区域需要用到mkswap命令mkswap /swapfile命令执行后一般会显示类似“Setting up swapspace version 1”的提示还会给出UUID和page size。看过输出之后再用swapon挂载启用swapon /swapfile启用之后立刻验证一下状态swapon --show free -hswapon --show能看到新swap文件的路径、类型、大小和优先级free -h能看到总量和当前使用量。如果free -h里swap那行的总量已经变大了说明启用成功。这个环节最常见的报错就是swapon: /swapfile: invalid argument。优先检查两个点一是文件是不是用fallocate创建的如果是删掉改用dd重新生成二是确认目录文件系统是不是tmpfs或特殊文件系统。还有一个小概率情况是内核编译时没有开启CONFIG_SWAP这种多见于极简定制的嵌入式环境普通服务器基本不会碰到。2.4 写入fstab实现开机自动挂载如果只是临时应急到swapon这一步就结束了重启后swap文件不会自动挂载。要想每次开机自动启用需要把它写进/etc/fstab/swapfile none swap defaults 0 0解释一下各字段含义第一段是swap文件路径第二段挂载点统一写成none第三段文件系统类型写swap第四段挂载选项用defaults第五和第六段分别是dump备份标志和fsck检查顺序swap区域都不需要全部填0。在systemd系的发行版里fstab的swap条目会自动被识别并生成对应的swap unit所以不需要额外手写systemd service。修改完fstab后先手动执行一次swapon -a看看能否把fstab中所有swap区域正确挂载。能成功挂载后建议重启一次或执行systemctl daemon-reload验证开机流程避免过几天重启后才发现swap没起来。这里还有个细节同一路径的swap文件在fstab里写none还是写swap作为挂载点两种写法都常见内核处理时没有本质区别。关键是把第一字段的路径写对别把/swapfile写成swapfile。3. 启用之后别急着收工swap相关参数调整与性能取舍3.1 swappiness别一律调0网上关于swap调优流传最广的一句话就是把swappiness改成0来“禁用swap”这个做法害了不少人。swappiness的取值范围是0到100默认通常是60它控制的是内核在回收内存时对匿名页和页缓存的倾向程度数值越大内核越倾向于把不活跃匿名页换到swap数值越小越倾向于回收页缓存。如果你把swappiness直接设成0内存紧张时内核会更激进地回收文件缓存file cache下次业务访问这些文件就只能重新读盘结果就是磁盘读取暴增、服务响应变慢甚至出现更频繁的OOM。我实测下来对服务器而言把swappiness调到10到20之间通常是合理的折中既不会让普通进程大量使用swap做无谓的换入换出又保留了缓冲能力桌面开发机如果内存够用保持默认反而更好。内存小于2G的设备我不建议调低太多因为删除文件缓存会影响本来就不宽裕的性能。临时调整可以直接写内核参数sysctl vm.swappiness10永久生效则写到配置文件里echo vm.swappiness10 /etc/sysctl.d/99-swap-tuning.conf sysctl --system3.2 dirty page与vfs_cache_pressure的关系swap调优经常会连带提到dirty_ratio、dirty_background_ratio和vfs_cache_pressure。这些参数虽然不直接属于swap文件但会共同影响系统在内存压力下的行为。dirty_background_ratio是后台开始写回脏页的阈值dirty_ratio是强制同步写回的阈值。当内存里的脏页比例过高时内核必须把数据落盘如果此时磁盘I/O已经被swap的换页写满系统就会明显卡顿。所以很多人加了swap之后发现系统更慢不一定是swap文件本身的问题而是内存和磁盘的I/O一起被顶满了。vfs_cache_pressure控制内核回收目录项和索引节点缓存的倾向默认值一般是100。内存紧张时提高这个值可以更快地回收缓存项但如果设得过高文件操作比如频繁ls、stat会因为缓存失效而变慢。我的建议是不要一次性同时改多个参数。每改一个用vmstat 1和free -h观察一段时间确认是否有副作用再动下一个。贪多只会让问题更难定位。3.3 多swap文件与优先级有些场景下你会遇到多个swap区域并存的情况比如系统自带了一个swap分区你又额外创建了一个swap文件。Linux内核允许同时启用多个交换区域最多可以到32个每个设备还有优先级之分。优先级数值越大越先被使用。手动指定优先级可以这样操作swapon -p 10 /swap_ssd swapon -p 20 /swap_nvme如果你混合使用了不同速度的磁盘比如高速SSD和普通机械盘把高优先级分配给高速盘是合理的策略。但我个人的建议仍然是单一swap文件管理最方便优先级机制只有在不得已的情况下才用。当多个swap区域同时存在时排查效率会明显下降因为你还要额外记住哪个swap对应哪个优先级策略。4. 扩容、收缩和彻底移除swap的实操套路4.1 swap分区与swap文件之间的迁移有时会遇到系统原本用的是swap分区你需要换成swap文件或者反过来从文件迁回分区。两者迁移有个共同原则必须保证swapoff时系统有足够内存承接被换出的页面否则内核会拒绝操作。从分区迁到文件顺序是先创建并挂载新的swap文件验证可用后再swapoff旧分区。从文件迁到分区正好相反先挂载新的swap分区确认系统已经在用新区域再swapoff旧文件最后删除文件。这样每一步操作时系统手里始终握着可用的swap安全性高得多。4.2 安全扩容和收缩操作的流程swap文件不是常规文件系统不能直接在线修改大小扩容和收缩本质上都是“重建”操作。完整流程如下# 1. 关闭目标swap文件 swapoff /swapfile # 2. 删除旧文件 rm -f /swapfile # 3. 先确认磁盘剩余空间足够 df -h / # 4. 按新大小创建文件用dd更稳 dd if/dev/zero of/swapfile bs1G count8 statusprogress # 5. 收紧权限并格式化 chmod 600 /swapfile mkswap /swapfile # 6. 重新启用并验证 swapon /swapfile swapon --show free -h如果swapoff时内存已经非常紧张系统会提示类似“Cannot allocate memory”的错误。这种情况不要硬删可以先临时创建一个新的swap文件顶上去再关闭旧的等于用“新旧轮换”的方式完成重建整个过程业务不受影响。fstab里的条目不需要改因为路径没变重建完成后自动对应。4.3 如何彻底移除swap移除swap也是运维里会碰到的需求。比如某台机器从临时测试机转正式生产不想再让swap参与内存回收。如果只是临时不看它直接执行swapoff -a但这个操作只在当前运行期生效重启后fstab里的条目又会把swap挂载回来。要彻底移除就得先swapoff再删除文件最后从fstab中删除对应行swapoff /swapfile rm -f /swapfile # 编辑 /etc/fstab删除或注释掉 /swapfile none swap defaults 0 0 这一行执行前还是那句老话先看free -h确认内存余量swapoff之后新换出的内存页面没有任何兜底承接很容易立刻触发OOM。另外fstab里如果还留着旧条目重启时systemd会因为找不到swap文件而报错虽然是能忽略的错误但日志里多出一堆红色警告总会让人不安。5. 我在实际环境中踩过的swap坑与排查记录5.1 fallocate导致的swapfile holes问题第一次踩这个坑时我还挺郁闷fallocate -l 4G /swapfile执行得很顺利mkswap也正常结果swapon直接报invalid argument。后来排查才发现fallocate对某些文件系统来说只是预分配了逻辑块并没有真正为文件写入全量数据swap文件存在“空洞”内核在挂载时校验不过。解决办法很朴素删掉文件改用dd从零写入重建。在那之后我养成了一个习惯凡是创建swap文件一律使用dd配合statusprogress虽然创建1G文件可能要等几十秒但每一步都在真实I/O中完成后续基本不会再因为文件空洞翻车。如果你是做自动化脚本也建议在脚本里直接用dd而不是fallocate这样在不同文件系统上跑都稳。5.2 swapon报invalid argument的常见原因swapon报invalid argument的原因不止文件空洞一种排查时要按优先级看几个方向可能原因判断方法处理方案swap文件有逻辑空洞用fallocate创建的删除后改用dd重建文件所在系统不支持swapfindmnt -T /swapfile查看实际文件系统换到ext4/xfs等常规文件系统文件权限过宽ls -l /swapfile显示非600执行chmod 600 /swapfile内核未启用swap支持查看内核config或dmesg极少见需要定制内核文件系统本身配置问题比如btrfs的某些初始化方式可改用loop设备或者干脆迁移目录这张表基本覆盖了我遇到过的绝大多数情况。遇到报错不要慌顺着这个顺序检查一遍大概率能定位到问题。5.3 开机失效与fstab的玄学还有一类问题很隐蔽手工swapon --show一切正常重启后swap神秘消失。排查的第一步是检查文件系统挂载时机。比如swap文件放在一个独立的数据盘上而fstab里数据盘的挂载顺序晚于swap挂载开机时系统自然找不到文件。其次要确认fstab路径和权限。路径写错、文件权限不是600、或文件名大小写写错都会导致启动失败。systemd环境下可以先执行systemctl daemon-reload然后swapon -a试试能否全部挂载。如果不行重点看启动日志里针对swap unit的报错信息比盲猜快得多。5.4 swap被疯狂占用时系统卡顿的定位最后说说“加了swap反而卡”的常见定位链路。这个现象我见过的次数最多通常不是swap文件的问题而是内存回收策略和磁盘I/O叠加的结果。先用free -h看swap使用量是否真正居高不下再用vmstat 1观察si和so两列这两列分别代表从swap读入和写入的速度。如果si、so长期非零说明系统确实在频繁换页如果只是swap里有占用但si、so接近零那只是历史数据残留不是实时瓶颈。然后配合iostat -x 1看磁盘的%util以及ps aux --sort-rss找出内存占用最高的进程。我处理过的一个典型案例是某采集进程存在内存泄漏内存持续增长内核只能疯狂换页整个机器iowait飙到90%以上最终方向是修复泄漏进程而不是继续加swap。后来我给自己定的流程就固定成了先看内存压力再看磁盘空间最后才决定要不要动swap文件。顺序一乱多出来的swap空间很容易变成一块漂亮的、但没有任何实际用途的磁盘占用。这也是我为什么每次都要强调“先想清楚再操作”增加swap空间本身不难难的是判断它是真正需要还是治标不治本。
阅读完成 · 觉得有帮助?
咨询建站