vm.swappiness 是 Linux 内核中控制内核将内存数据交换(Swap)到磁盘的积极程度。它决定了内核在内存紧张时,是更倾向于回收文件页(File-backed pages,即缓存),还是更倾向于交换出匿名页(Anonymous pages,即应用程序内存)。
核心概念:内存回收的两种选择
当 Linux 系统需要更多物理内存时,它有两种选择来释放空间:
- 丢弃文件缓存(Page Cache): 系统会自动把磁盘上的文件加载到内存作为缓存。回收这些内存很简单,直接丢弃即可(如果内容没变)或写回磁盘(如果内容变了)。
- 交换匿名内存(Swap): 应用程序正在使用的堆、栈数据(匿名页)。要回收这部分内存,必须将其写入 Swap 分区(磁盘),这会产生 I/O 开销。
vm.swappiness 就是用来权衡这二者的权重。
参数范围与含义
该参数的值是一个整数,范围通常是 0 到 100。
- 0:
- 并不意味着完全禁用 Swap。
- 这告诉内核:除非物理内存已经到了极度危险的边缘(Free 内存 + 文件缓存 < 高水位线),否则绝对不要发生 Swap。
- 目的是最大限度地保留应用程序代码和数据在物理内存中,防止延迟。
- 1 - 10:
- 表示极低频率地使用 Swap。
- 常用于数据库服务器(如 MySQL、PostgreSQL)或对延迟敏感的应用(如 Java JVM),以避免
Swap 抖动导致服务卡顿。
- 60(默认值):
- 大多数 Linux 发行版的默认设置。
- 这是一个折中的方案:内核会适度地使用 Swap,同时保留一定的文件缓存,以维持系统的整体吞吐量。
- 100:
- 表示内核会非常积极地使用 Swap。
- 内核会倾向于把应用程序的数据换出到磁盘,从而空出更多的物理内存来作为文件缓存(Page Cache)。这可能有助于提升某些 I/O 密集型操作的性能,但会牺牲应用程序的响应速度。
如何查看和修改
查看当前值
cat /proc/sys/vm/swappiness
# 或者
sysctl vm.swappiness
临时修改(重启后失效)
如果你想将值改为 10:
sudo sysctl -w vm.swappiness=10
# 或者
echo 10 | sudo tee /proc/sys/vm/swappiness
永久修改(重启后生效)
编辑 /etc/sysctl.conf 文件:
sudo vim /etc/sysctl.conf
在文件末尾添加或修改以下行:
保存退出后,执行以下命令使配置立即生效:
最佳实践场景
数据库服务器 (MySQL, Redis, PostgreSQL)
推荐值:0 或 1 或 10
数据库通常自带内存管理机制(如 Buffer Pool)。如果操作系统把数据库的缓存交换到磁盘 Swap 中,性能会呈断崖式下跌。因此,通常设置为 1 或 10,尽量让数据库常驻物理内存。
注意:在 Linux Kernel 3.5+ 版本中,设置为 0 可能会导致在还有剩余缓存可回收时触发 OOM (Out of Memory) 杀手,因此通常建议设置为 1 而不是 0,作为保险。
大数据节点 (Hadoop, Elasticsearch, Spark)
推荐值:1
Java 应用(JVM)非常讨厌 Swap。一旦堆内存被换出,GC(垃圾回收)扫描时会触发大量的磁盘读取,导致长时间的 “Stop-the-world” 卡顿。
Kubernetes 节点
推荐值:通常禁用 Swap
K8s 默认要求关闭 Swap。如果开启,也应将 swappiness 设为极低,保证 Pod 性能的可预测性。
桌面系统 / 普通 Web 服务器
推荐值:60 (默认)
对于桌面用户,保持一定的缓存能让打开文件、启动 App 更快。如果物理内存充足,默认值通常没问题。
常见误区
- 误区: ``swappiness=0
等于swapoff。
- 事实: 即使设为 0,当物理内存耗尽且无法回收 Page Cache 时,内核依然会使用 Swap 来避免系统崩溃。要完全禁用 Swap,必须使用
swapoff -a 命令。
- 误区:
内存没用完就开始 Swap,说明系统有问题。
- 事实: 不一定。如果
swappiness 是 60,且系统有大量文件读写,内核可能会觉得把不常用的 App 内存换出,腾出地方给文件做缓存是更优的选择。这是符合预期的行为。
总结
- vm.swappiness = 60:平衡模式(默认)。
- vm.swappiness = 10 (或 1):延迟敏感模式(数据库、Java 应用首选),宁愿丢缓存也不愿换出程序内存。
- vm.swappiness = 100:吞吐量优先模式,为了文件缓存最大化而牺牲程序响应速度。