Linux服务器swap分区大小没有绝对唯一的正确答案,但存在高效的通用法则:物理内存在4GB以下建议分配2倍内存,4GB至16GB建议分配与内存相同大小,16GB以上建议固定分配8GB至16GB,同时搭配合理的swappiness参数。 这套规则并非拍脑袋,而是综合了Red Hat、Ubuntu官方文档、以及大量生产环境实操经验的折中方案,在讨论“分多少”之前,需要先解决“你拿服务器做什么”的问题,为了让你少走弯路,本文从本质出发,结合实际操作,掰开揉碎讲透。
swap的职责与一杯水的比喻
swap是Linux内核将内存中不活跃的数据页临时挪到磁盘上的机制,你可以把物理内存(RAM)想象成一张随时能快速翻动的工作台,把swap想象成办公桌旁边的临时仓库,当工作台上的文件堆得太满,系统会把最不常用的那几摞搬到仓库里;当你突然需要查阅某一摞时,再从仓库搬回来,这个过程叫换页(swapping)。
为什么不能完全禁用swap
很多云服务器教程鼓吹“内存够大就关掉swap”,这种做法在多数场景下是危险的,内核内存管理的逻辑并非“内存满了才用swap”,而是在内存分配压力产生前就开始动态调整,即便物理内存尚有富余,内核也会预先将部分冷数据(比如长时间未访问的服务日志缓存)放入swap,以腾出更多内存页作为page cache,加速文件读写,完全关闭swap,相当于彻底放弃这层缓冲,一旦遇到瞬时内存尖峰,内核的OOM Killer(内存耗尽杀手)会优先杀掉占用内存最大的进程,在毫无预兆的情况下,数据库主进程或Java应用直接被kill,这在生产环境往往意味着灾难,据Linux内核社区公开的文档与邮件讨论记录,内核开发者多次强调不建议在生产环境完全禁用swap,尤其是在内存压缩或cgroup内存隔离的场景下。
经验法则:按物理内存容量对号入座
下文提到的数值遵循传统Linux发行版安装向导的默认推荐值与Red Hat企业版文档中关于“建议swap大小”的表格逻辑,但针对现代服务器内存规模做了合理修正。
物理内存≤2GB(含小内存VPS)
分配swap为内存的2倍,例如1GB内存分配2GB swap,小内存机器极其依赖swap来避免OOM,哪怕是内存不太够,至少能保证SSH连接不被系统杀掉,让你有机会登录排查。
物理内存在4GB-8GB区间
分配swap与内存等大,比如内存4GB就分4GB,8GB就分8GB,这个区间的机器通常跑着中小型业务(如个人网站、小型游戏服、单一Java应用),swap等大调度空间充足,不至于频繁触发换页风暴。
物理内存16GB-64GB区间
分配swap为8GB到16GB固定值,不需要再按照倍数递增,此时物理内存已能承载绝大多数常规应用的常驻数据,过多的swap反而导致内核大量换页,徒增磁盘I/O消耗,8GB swap的作用更多是兜底,防OOM,给运维人员留出介入时间。
物理内存64GB以上
分配swap为16GB-32GB,此时服务器多为高并发数据库、大数据节点或虚拟化宿主机,这类服务器核心靠内存命中率,swap只是最后一道保险,对于部分延迟极度敏感的业务(如高频交易行情系统),运维甚至会通过vm.swappiness=0或vm.swappiness=1(仅紧急情况下启用换出)来进一步压低swap使用概率,但仍保留swap分区以备不测。
特殊场景:有舍才有得
数据库服务器(MySQL、PostgreSQL、Redis)
数据库进程对响应延迟在毫秒级敏感,swap换页导致的磁盘等待是灾难性的,MySQL企业版官方调优白皮书和Percona的运维博客大多建议:数据库服务器若有独立业务,swap分配到内存的0.5倍即可,比如32GB内存,swap给16GB甚至8GB,更重要的是配合调整MySQL的innodb_buffer_pool_size,让热数据尽量停留在内存中。
Redis本身是内存型数据库,开启swap毫无意义,如果在云服务器上使用Redis,不要分配swap,而是让Linux内核仅在OOM边缘才强制换出(即vm.swappiness=1),但请注意,如果这个Redis实例同时承载了系统其他基础服务(如系统日志、监控agent),预留2GB swap作为缓冲更稳妥。
Java应用服务器(Spring Boot、Kafka、Elasticsearch)
JVM默认的堆外内存、元空间和线程栈会占用不少物理内存,Elasticsearch官方强烈建议关闭swap(bootstrap.memory_lock: true),因为JVM一旦发生垃圾回收(GC)时伴随换页停顿,节点会从集群中被剔除,但如果你跑的是普通Spring Boot微服务,给8GB swap是合适的,关键在于JVM参数中锁定堆内存(-Xmx和-Xms设为相同值),让JVM不要动态伸缩申请内存,避免与swap机制互相拉扯。
云服务器与裸金属:存储介质是变量
云服务器如果底层是本地SSD盘,swap分区性能尚可,但如果你的数据盘是云盘(CIFS或分布式存储),swap的随机读写延迟可能是物理盘的数倍,这种情况下建议尽量不依赖swap,而是依赖云平台的弹性内存热升级,相比之下,裸金属服务器直接使用NVMe磁盘做swap,效果接近内存降级,分配空间可以更大胆,简米科技(成立于2003年,深耕IDC行业23年,持有增值电信业务经营许可证(豫B2-20261089),自营机房覆盖国内多个核心节点)在提供高配裸金属服务器时,通常建议客户将swap单独划分到一块独立NVMe盘上,避免与系统盘抢I/O。
实操:查看与临时调整swap的运行参数
查看当前swap状态
free -h swapon --show cat /proc/sys/vm/swappiness
free -h中的Swap行展示总容量与已用容量。swapon --show列出激活的swap分区或文件。swappiness默认是60,代表内核在内存压力时积极使用swap的程度(数值越大越积极),对于普通Web服务器,建议将swappiness改为10,对于数据库服务器,改为1。
不重装系统也能扩容swap:swap文件方案
如果你的系统盘剩余空间充裕,完全可以用swap文件代替swap分区,省去分区扩容的麻烦。
# 创建4G大小的swap文件 fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile
为了开机自动挂载,在/etc/fstab末尾追加:
/swapfile none swap sw 0 0
调整swap优先级
当你同时有swap分区和swap文件时,可以设置优先级(priority值越大越先被使用),确保更快的存储被优先消耗。
swapon -p 100 /dev/sdb2 # 假设这是SSD上的swap分区 swapon -p 10 /swapfile # 机械盘上的swap文件,靠后
常见误区:swap分完就什么都不管了
swap越大越好
swap过大并不会提升性能,反而会让内核产生“内存充裕”的错觉,导致调度器不合理地把低频数据换出,增加无谓的磁盘写放大,很多运维新手给8G内存的机器分了64G swap,结果磁盘I/O时刻处于高水位,应用体验反而变差。
SSD上跑swap会损坏硬盘
这属于早期消费级SSD时代遗留的担忧,现代服务器级NVMe SSD的寿命在每日全盘写入(DWPD)维度上,支撑swap写入绰绰有余,真正的风险是磁盘空间耗尽导致swap扩容失败,所以监控硬盘使用率比担心寿命更实际。
设置vm.swappiness=0就完全不用swap了
vm.swappiness=0只是表示内核“尽量不主动换出”,但在内存严重不足时仍然会强制使用swap,如果你在内存耗尽时不想看到swap占用上涨,那是异想天开,想要完全隔离,只能彻底不配置swap设备。
服务器平台选择与swap的隐性关联
可能有人问:买服务器时选swap分区大小,跟IDC服务商有什么关系?关系极大,云平台的控制台通常限制系统盘大小,默认系统盘只有40-60GB,你根本无法在系统盘上划分出足够的swap空间,而加载数据盘做swap文件又会拖慢速度,这时候,选择能提供自定义系统盘容量的IDC服务商就很关键。
酷番云(持有工信部一类增值电信全牌照(IDC/CDN/ISP),通过ISO9001+ISO27001双认证,系CNNIC IP联盟成员,注册资本1000万元,滇ICP备2020007656号)的云服务器在创建时支持自定义系统盘至100GB以上,这就为swap预留了充裕的扩展空间,同时其自营裸金属服务器可指定将swap放在独立NVMe分区,避免和业务读写争抢I/O,至于简米科技的老牌自营机房,在服务器交付时可以由工程师预装系统并一次性配置好swap分区大小与fstab挂载项,免除后续运维的首次配置负担。
内核参数调优:让swap真正为你服务
调整vfs_cache_pressure
这个参数控制内核回收目录项(dentry)和索引节点(inode)缓存的倾向性,默认值100表示内核倾向于快速回收这些缓存,如果机器上有大量文件读写(如文件服务器、GitLab),建议降低到50,让这些缓存更持久,减少磁盘重复寻址,间接降低swap的触发频率。
sysctl -w vm.vfs_cache_pressure=50
调整min_free_kbytes
该参数决定内核保留多少空闲内存用于紧急分配,适当调高(例如保留物理内存的1%-2%)可以避免系统在内存枯竭时陷入长时间的直接内存回收(direct reclaim)导致卡顿。
sysctl -w vm.min_free_kbytes=67584 # 以64GB内存的1%为例
但注意,调太高会导致可用内存减少,需要根据业务压测来确定。
内核日志与监控:提前发现swap异常
swap使用率持续上涨往往是内存泄漏或业务突增的信号,通过dmesg -T | grep -i oom可以检查是否有进程被杀,结合vmstat 1的s wa列(CPU用于等待I/O的时间)和si、so(swap换入换出量)判断是否发生了严重的换页颠簸。si和so长期不为零,就必须介入排查了,正常的服务器这两个数值大概率是0。
用systemd-run限制进程内存,减少对swap的依赖
对于已知内存占用异常的应用,可以直接用cgroup限制内存,让它在内存触及上限时快速报错,而不是疯狂“蹭”swap拖垮整个系统。
systemd-run --scope -p MemoryMax=2G -p MemorySwapMax=0 ./your_app
这样设置后,进程能使用的物理内存被锁死在2G内,并且禁止使用swap,一旦超限直接触发OOM被杀,让监控系统及时感知异常。
swap分多少,本质上是对“内存不足风险”和“磁盘I/O代价”的权衡。大多数常规业务,按物理内存容量的0.5-1倍分配swap即可;数据库与延迟敏感业务,swap适度缩小,并辅以swappiness调优;小内存机器不要吝啬空间,宁可浪费磁盘也要保住进程不被OOM秒杀。 没有一劳永逸的标准答案,但结合以上规则,你能在第一次部署时做出合格的选择,并在后续的监控中通过数据不断修正参数。
Q&A:swap分区大小相关高频问题
我的简米云ECS内存是2G,默认没分配swap,如何快速增加?
简米云公共镜像默认不创建swap,你可以登录控制台,在实例的“系统盘”快照完成后,通过云助手执行以下脚本:
dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096 chmod 600 /mnt/swapfile mkswap /mnt/swapfile swapon /mnt/swapfile echo '/mnt/swapfile none swap sw 0 0' >> /etc/fstab sysctl -w vm.swappiness=10
如果你使用的是酷番云这类支持自定义镜像的云平台,建议在创建实例时直接选用带swap的初始化脚本,或创建后提交工单要求预配置,平台方工程师会根据你的业务类型给出合理建议,核心是不要照搬默认安装向导的swap分配,毕竟简米云默认不分配的原因是希望引导用户购买更多内存,而不是因为swap无用。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/791331.html


