【运维】Linux交换空间实战:如何高效利用硬盘扩展内存并优化性能

张开发
2026/4/3 17:12:35 15 分钟阅读
【运维】Linux交换空间实战:如何高效利用硬盘扩展内存并优化性能
1. 为什么需要交换空间当你在Linux服务器上跑一个内存消耗特别大的应用时经常会遇到内存不足的报错。这时候系统要么直接杀死进程要么变得卡顿不堪。我遇到过最惨的情况是MySQL因为内存不足突然崩溃导致线上服务中断了半小时。其实Linux早就考虑到了这种情况它提供了一种叫**交换空间(Swap Space)**的机制。简单来说就是把硬盘上的一部分空间虚拟成内存来用。虽然硬盘速度比内存慢得多但总比直接崩溃强对吧我在管理一些老旧服务器时这个功能简直是救命稻草。2. 创建交换空间的三种姿势2.1 用单独分区做交换空间这是最传统的做法适合刚装系统时就规划好的场景。我一般会分出一个4-8GB的独立分区# 查看当前磁盘分区情况 fdisk -l # 对新分区设置交换空间类型 mkswap /dev/sdb2 # 立即启用 swapon /dev/sdb2不过现在很多云主机都是直接给一块大磁盘重新分区比较麻烦。这时候我更推荐下面这种方法。2.2 用文件实现交换空间这是我用得最多的方案特别适合临时扩容的场景。上周刚帮一个跑TensorFlow的同事用这招解决了OOM问题# 创建一个4GB的交换文件 sudo dd if/dev/zero of/swapfile bs1M count4096 # 设置权限重要 sudo chmod 600 /swapfile # 格式化为交换空间 sudo mkswap /swapfile # 立即启用 sudo swapon /swapfile实测在SSD上这样做性能比机械硬盘快3-5倍。不过要注意频繁交换会损耗SSD寿命建议只在紧急情况下使用。2.3 动态调整交换文件大小有时候我们不确定需要多大的交换空间。这时候可以用fallocate命令它比dd更快而且能动态调整# 快速创建8GB交换文件 sudo fallocate -l 8G /swapfile # 如果需要扩容到16GB sudo swapoff /swapfile sudo fallocate -l 16G /swapfile sudo mkswap /swapfile sudo swapon /swapfile3. 让交换空间开机自动加载配置完不设置开机启动的话重启后就白忙活了。我吃过这个亏所以现在每次都会做这个步骤# 先确认交换文件路径 sudo swapon --show # 编辑fstab文件 sudo vim /etc/fstab # 添加这行以/swapfile为例 /swapfile none swap sw 0 0有个坑要注意如果用的是NVMe硬盘设备名可能是/dev/nvme0n1p1这种形式在fstab里最好用UUID来标识更稳妥# 先查看UUID sudo blkid # 然后在fstab里这样写 UUID123e4567-e89b-12d3-a456-426614174000 none swap sw 0 04. 交换空间性能调优实战4.1 该设置多大的交换空间这个问题我被问过无数次。根据我的经验内存4GB设置内存的2倍内存4-16GB等于内存大小内存16GB8-16GB足够但具体还要看应用场景。比如跑MySQL的服务器我会这样计算# 先查看当前内存使用峰值 free -h # 再结合MySQL配置的buffer pool大小 # 总交换空间 (峰值内存 - 物理内存) * 1.24.2 关键内核参数调优通过这几个参数可以控制交换行为的积极性# 查看当前设置 cat /proc/sys/vm/swappiness # 临时修改推荐值10-60 sudo sysctl vm.swappiness30 # 永久生效 echo vm.swappiness30 /etc/sysctl.conf另一个重要参数是vfs_cache_pressure控制内核回收用于文件和目录缓存的内存的倾向# 默认值100缓存敏感型应用可以设低些 sudo sysctl vm.vfs_cache_pressure504.3 监控交换空间使用情况我常用的几个监控命令# 实时监控按q退出 watch -n 1 free -h; swapon --show # 查看哪些进程在用交换空间 sudo smem -s swap -r | head # 更详细的统计 sudo vmstat 1 5如果发现某个进程占用了过多交换空间可以用这个命令进一步分析# 先找出进程ID top # 然后查看该进程的内存映射 sudo pmap -x 进程ID5. 什么时候该禁用交换空间虽然交换空间很实用但在某些场景下最好禁用数据库服务器特别是MySQL、Redis这类对内存敏感的服务使用交换空间反而会导致性能雪崩。我吃过这个亏一个本该快速失败的查询因为用了交换空间拖垮了整个数据库。高性能计算做科学计算或者AI训练时宁愿让程序报错也不要让它偷偷用交换空间否则训练时间可能从几小时变成几天。禁用方法很简单# 临时禁用所有交换空间 sudo swapoff -a # 永久禁用需要删除/etc/fstab里的相关配置 # 并删除交换文件 sudo rm /swapfile6. 进阶技巧zswap和zram对于内存真的紧张的环境我推荐两个更高级的方案zswap相当于在内存和交换空间之间加了个压缩层能显著提升性能。配置方法# 编辑grub配置 sudo vim /etc/default/grub # 在GRUB_CMDLINE_LINUX添加 GRUB_CMDLINE_LINUXzswap.enabled1 zswap.compressorlz4 # 更新grub sudo update-grubzram直接把内存的一部分作为压缩交换设备适合内存不算太小但需要临时扩容的场景# 启用zram sudo modprobe zram # 设置大小为2GB echo 2G /sys/block/zram0/disksize # 启用为交换设备 mkswap /dev/zram0 swapon /dev/zram0这两种方案我在树莓派上用得最多效果比传统交换空间好很多。7. 常见问题排坑指南问题1swapon报invalid argument错误可能是文件系统不支持交换空间试试ext4或xfs也可能是文件没正确格式化重新执行mkswap问题2交换空间使用率为0但内存已满检查swappiness值是否设得太低用sudo dmesg | grep oom看看是不是触发了OOM Killer问题3SSD寿命担忧可以用sudo smartctl -a /dev/sda查看SSD磨损情况建议在/etc/sysctl.conf添加vm.dirty_background_ratio 5 vm.dirty_ratio 10最后说个真实案例有次我们服务器内存泄漏物理内存耗尽后开始狂用交换空间。虽然服务没挂但响应速度从200ms降到了5秒。后来通过监控及时发现在业务低峰期重启服务解决了问题。这个故事告诉我们交换空间是最后的保险不能当作常规方案来用。

更多文章